7.取消一个线程
有时,我们想让一个线程可以要求另一个线程终止,线程有方法做到这一点,与信号处理一样,线程可以在被要求终止时改变其行为。
先来看用于请求一个线程终止的函数:
#include <pthread.h>
int pthread_cancel(pthread_t thread);
这个函数简单易懂,提供一个线程标识符,我们就可以发送请求来取消它。
线程可以用pthread_setcancelstate设置自己的取消状态。
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
参数说明:
state:可以是PTHREAD_CANCEL_ENABLE允许线程接收取消请求,也可以是PTHREAD_CANCEL_DISABLE忽略取消请求。
oldstate:获取先前的取消状态。如果对它没兴趣,可以简单地设置为NULL。如果取消请求被接受了,线程可以进入第二个控制层次,用pthread_setcanceltype设置取消类型。
#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
参数说明:
type:可以取PTHREAD_CANCEL_ASYNCHRONOUS,它将使得在接收到取消请求后立即采取行动;另一个是PTHREAD_CANCEL_DEFERRED,它将使得在接收到取消请求后,一直等待直到线程执行了下述函数之一后才采取行动:pthread_join、pthread_cond_wait、pthread_cond_timedwait、pthread_testcancel、sem_wait或sigwait。
oldtype:允许保存先前的状态,如果不想知道先前的状态,可以传递NULL。
默认情况下,线程在启动时的取消状态为PTHREAD_CANCEL_ENABLE,取消类型是PTHREAD_CANCEL_DEFERRED。
下面编写代码thread6.c,主线程向它创建的线程发送一个取消请求。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *thread_function(void *arg);
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0)
{
perror("Thread create failed!");
exit(EXIT_FAILURE);
}
sleep(4);
printf("Canceling thread.../n");
res = pthread_cancel(a_thread);
if (res != 0)
{
perror("Thread cancel failed!");
exit(EXIT_FAILURE);
}
printf ("Waiting for thread to finished.../n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror ("Thread join failed!");
exit(EXIT_FAILURE);
}
printf("Thread canceled!");
exit(EXIT_FAILURE);
}
void *thread_function(void *arg)
{
int i;
int res;
res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (res != 0)
{
perror("Thread setcancelstate failed!");
exit(EXIT_FAILURE);
}
res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
if (res != 0)
{
perror("Thread setcanceltype failed!");
exit(EXIT_FAILURE);
}
printf("thread_function is running.../n");
for (i = 0; i < 10; i++)
{
printf("Thread is still running (%d).../n", i);
sleep(1);
}
pthread_exit(0);
}
编译这个程序:
gcc -D_REENTRANT thread6.c -o thread6 –lpthread
运行这个程序:
$ ./thread6
thread_function is running...
Thread is still running (0)...
Thread is still running (1)...
Thread is still running (2)...
Thread is still running (3)...
Canceling thread...
Waiting for thread to finished...
8.多线程
之前,我们所编写的代码里面都仅仅是创建了一个线程,现在我们来演示一下如何创建一个多线程的程序。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM 6
void *thread_function(void *arg);
int main()
{
int res;
pthread_t a_thread[NUM];
void *thread_result;
int index;
for (index = 0; index < NUM; ++index) {
res = pthread_create(&a_thread[index], NULL, thread_function, (void *)index);
if (res != 0)
{
perror("Thread create failed!");
exit(EXIT_FAILURE);
}
sleep(1);
}
printf("Waiting for threads to finished.../n");
for (index = NUM - 1; index >= 0; --index)
{
res = pthread_join(a_thread[index], &thread_result);
if (res == 0)
{
printf("Picked up a thread:%d/n", index + 1);
}
else
{
perror("pthread_join failed/n");
}
}
printf("All done/n");
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
int my_number = (int)arg;
int rand_num;
printf("thread_function is running. Argument was %d/n", my_number);
rand_num = 1 + (int)(9.0 * rand()/(RAND_MAX + 1.0));
sleep(rand_num);
printf("Bye from %d/n", my_number);
pthread_exit(NULL);
}
编译这个程序:
gcc -D_REENTRANT thread7.c -o thread7 –lpthread
运行这个程序:
$ ./thread7
thread_function is running. Argument was 0
thread_function is running. Argument was 1
thread_function is running. Argument was 2
thread_function is running. Argument was 3
thread_function is running. Argument was 4
Bye from 1
thread_function is running. Argument was 5
Waiting for threads to finished...
Bye from 5
Picked up a thread:6
Bye from 0
Bye from 2
Bye from 3
Bye from 4
Picked up a thread:5
Picked up a thread:4
Picked up a thread:3
Picked up a thread:2
Picked up a thread:1
All done
9.小结
本文主要介绍了Linux环境下的多线程编程,介绍了信号量和互斥量、线程属性控制、线程同步、线程终止、取消线程及多线程并发。
本文比较简单,只作为初学Linux多线程编程入门之用。