Chinaunix首页 | 论坛 | 博客
  • 博客访问: 168614
  • 博文数量: 39
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 214
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-21 11:10
文章分类

全部博文(39)

文章存档

2017年(6)

2016年(1)

2015年(6)

2014年(26)

我的朋友

分类: C/C++

2014-05-08 16:47:06


一个线程的终止的方式,可以简单分成两类:
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
#


 



阅读(1544) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~