首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

pthread 简洁使用指南(三) 线程的终止

2012-09-15 
pthread 简要使用指南(三) 线程的终止pthread_create()的帮助文档里面,明确指出,一个线程的终止有如下的四

pthread 简要使用指南(三) 线程的终止

    pthread_create()的帮助文档里面,明确指出,一个线程的终止有如下的四种方式:
    
    * 本线程中调用pthread_exit(),同一进程里面调用pthread_join()的其他线程可以获取该线程的退出值。
    * 本线程的线程函数start_routine执行结束返回。
    * 本线程被pthread_cancel()取消。
    * 本线程所在的进程退出。

    pthread_exit(), 原型:
    void pthread_exit(void *retval);
    该函数在线程中的作用,与exit()在进程中的作用类似。执行到pthread_exit(),线程将会直接终止,并使用pthread_exit的参数作为线程的退出状态值。如果线程是joinable的,其线程ID和退出状态值将一直保留到调用进程中的某个其他线程调用pthread_join函数。指针retval不能指向局部于调用线程的对象,因为线程终止时这些对象也消失。

    pthread_cancel(),原型:
    int pthread_cancel(pthread_t thread);
    pthread_cancel()发送一个取消请求给目标线程,该函数需要目标线程配合。目标线程如何操作,取决于该线程的可撤销状态及类型(cancelability state and type)。
    可撤销状态有两个值:PTHREAD_CANCEL_ENABLE,PTHREAD_CANCEL_DISABLE。该状态可以通过pthread_setcancelstate()函数来修改。这个状态决定该线程是否处理取消请求。如果PTHREAD_CANCEL_ENABLE,则处理取消请求,PTHREAD_CANCEL_DISABLE,则不处理取消请求。
    可撤销类型同样也有两个值:PTHREAD_CANCEL_DEFERRED,PTHREAD_CANCEL_ASYNCHRONOUS。该类型可以通过pthread_setcanceltype()函数来修改。可撤销状态为PTHREAD_CANCEL_ENABLE时,可撤销类型值才会被判断。PTHREAD_CANCEL_ASYNCHRONOUS 立即执行取消信号,PTHREAD_CANCEL_DEFERRED 运行到下一个取消点然后退出线程。

    PTHREAD_CANCEL_DEFERRED情形下,pthread_cancel()给目标线程设置一个取消标志。目标线程在运行中的某些地方会查看自己是否存在取消请求,如果有,就立刻终止执行后继代码并退出。这些查看是否存在取消请求的地方,称之为取消点(Cancelation-point)。

   下面的代码,是在suse linux中的pthread_cancel编程指南中例子的基础上修改得到:

#include <pthread.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#define handle_error_en(en, msg) \    do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)static void * thread_func(void *ignored_argument){    int s;    pthread_t *pthr = (pthread_t *)ignored_argument;    /* Disable cancellation for a while, so that we don't    immediately react to a cancellation request */    s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);    if (s != 0)        handle_error_en(s, "pthread_setcancelstate");    printf("thread_func(id %u (0x%x)): started; cancellation disabled\n",            (unsigned int)(*pthr), (unsigned int)(*pthr));    sleep(5);    printf("thread_func(id %u (0x%x)): about to enable cancellation\n",             (unsigned int)(*pthr), (unsigned int)(*pthr));    s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);    if (s != 0)        handle_error_en(s, "pthread_setcancelstate");    /* sleep() is a cancellation point */    sleep(10);        /* Should get canceled while we sleep */    /* Should never get here */    printf("thread_func(id %u (0x%x)): not canceled!\n",             (unsigned int)(*pthr), (unsigned int)(*pthr));    return NULL;}int main(void){    pthread_t thr1;    pthread_t thr2;    void *res;    int s;    /* Start a thread and then send it a cancellation request */    s = pthread_create(&thr1, NULL, &thread_func, (void*)&thr1);    if (s != 0)        handle_error_en(s, "pthread_create 1");    s = pthread_create(&thr2, NULL, &thread_func, (void*)&thr2);    if (s != 0)        handle_error_en(s, "pthread_create 2");    sleep(2);           /* Give thread a chance to get started */    printf("main(): sending cancellation request\n");    s = pthread_cancel(thr1);    if (s != 0)        handle_error_en(s, "pthread_cancel");    /* Join with thread to see what its exit status was */    s = pthread_join(thr1, &res);    if (s != 0)        handle_error_en(s, "pthread_join");    if (res == PTHREAD_CANCELED)        printf("main(): thread 1 was canceled\n");    else        printf("main(): thread 1 wasn't canceled (shouldn't happen!)\n");    s = pthread_join(thr2, &res);    if (s != 0)        handle_error_en(s, "pthread_join");    if (res == PTHREAD_CANCELED)        printf("main(): thread 2 was canceled\n");    else        printf("main(): thread 2 wasn't canceled (shouldn't happen!)\n");    exit(EXIT_SUCCESS);}



热点排行