一个线程的终止的方式,可以简单分成两类:
1. 自己终止
a> 运行完毕,返回,返回值是线程的退出码;
b> 在运行过程中,调用pthread_exit
2. 被迫终止或者非正常退出(线程A终止线程B)
a> 线程A使用pthread_cancel
b> 线程A使用pthread_kill;
pthread_cancel这种形式,需要注意的是:
a). 线程A调用pthread_cancel,线程B对于cancel的信号来说,是可以忽略掉的。这个开关可以通过
pthread_setcancelstate来进行设置,
PTHREAD_CANCEL_ENABLE(缺省)和 PTHREAD_CANCEL_DISABLE 。
b). 线程A调用完pthread_cancel以后,
线程B不是马上就会结束掉线程,需要运行到取消点;换句话说,如果线程B中,运行的上下文中,根本不存在取消点,那么线程B仍然不会被终止掉,这个需要有其注意,但是可以通过调用函数pthread_testcancel()添加取消点。POSIX线程存在的一些取消点:thread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()、sleep()等会引起阻塞的系统调用都是取消点。
pthread_kill这种形式如果在线程里不处理信号,则
按照默认的方式,会结束掉进程(不一定是想要的效果)。如果线程B不存在取消点,又不想添加pthread_testcancel()来不断地检查,就可以用这种方式,添加一个信号处理,在信号处理的地方释放线程B的资源,以及退出线程。
例子1,使用pthread_cancel来终止线程:
#include
#include
#include
#include
#include
#include
#include
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; /*锁*/
void *thread1(void *arg){
unsigned int i = 0;
printf("thread 1 is executing \n");
pthread_mutex_unlock(&mutex); /*打印完,释放信号*/
while(1){
i++;
/*
* 如果没有下面这一行,则主进程调用的thread_cancel会不起作用
* 因为这个while循环里面,并不能存在“取消点”。
*/
pthread_testcancel();
}
return NULL;
}
int main(void){
pthread_t tid;
pthread_mutex_lock(&mutex);
pthread_create(&tid,NULL,thread1,NULL);
pthread_mutex_lock(&mutex); /*等待线程释放锁*/
pthread_mutex_unlock(&mutex);
pthread_cancel(tid); /*这里我们调用pthread_cancel想要终止thread1*/
while(1){
if(pthread_kill(tid, 0) == 0){/*如果pthread_kill第二个参数不是信号,而是0的时候可以检查线程是否还在*/
printf("thread tid=%lu is exist \n", (unsigned long)tid);
}else{
printf("thread tid=%lu is exited \n", (unsigned long)tid);
return 0;
}
sleep(5);
printf("Main Thread is going on !!! \n");
}
return 0;
}
执行结果:
# gcc -lpthread p1.c
# ./a.out
thread 1 is executing
thread tid=3077352304 is exist
Main Thread is going on !!!
thread tid=3077352304 is exited
#
例子2,使用pthread_kill :
#include
#include
#include
#include
#include
#include
#include
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
/* Signale wrapper. */
void * signal_set (int signo, void (*func)(int))
{
int ret;
struct sigaction sig;
struct sigaction osig;
sig.sa_handler = func;
sigemptyset (&sig.sa_mask);
sig.sa_flags = 0;
ret = sigaction (signo, &sig, &osig);
if (ret < 0)
return (SIG_ERR);
else
return (osig.sa_handler);
}
/*SIGQUIT的信号处理函数*/
void thread1_SIGQUIT_func(int arg){
printf("thread1 is exit \n", __FUNCTION__, __LINE__);
pthread_exit(0); /*退出线程*/
return ;
}
void *thread1(void *arg){
unsigned int i = 0;
printf("thread1 is executing \n");
signal_set(SIGQUIT, thread1_SIGQUIT_func);
pthread_mutex_unlock(&mutex);
while(1){
i++;
}
return NULL;
}
int main(void){
pthread_t tid;
pthread_mutex_lock(&mutex);
pthread_create(&tid,NULL,thread1,NULL);
pthread_mutex_lock(&mutex); //等待thread1释放信号
pthread_mutex_unlock(&mutex);
//pthread_cancel(tid);
printf("We send a signal SIGQUIT to thread %lu \n", (unsigned long)tid);
pthread_kill(tid,SIGQUIT); //发送信号SIGQUIT给thread1
while(1){
if(pthread_kill(tid, 0) == 0){
printf("thread tid=%lu is exist \n", (unsigned long)tid);
}else{
printf("thread tid=%lu is exited \n", (unsigned long)tid);
return 0;
}
sleep(5);
printf("Main Thread is going on !!! \n");
}
return 0;
}
执行结果:
# ./a.out
thread1 is executing
We send a signal SIGQUIT to thread 3076156272
thread tid=3076156272 is exist
thread1 is exit
Main Thread is going on !!!
thread tid=3076156272 is exited
#
阅读(1596) | 评论(0) | 转发(0) |