带参数0的pthread_cleanup_pop

时间:2012-10-27 13:52:04

标签: pthreads

根据pthread_cleanup_pop的手册页,如果此函数的参数非零,则会调用清理处理程序,否则匹配的pthread_cleanup_push安装的清理处理程序将被删除。

我使用的是Ubuntu 3.2.0-32-generic-pae。 但是我看到虽然参数是0,但是调用清理处理程序。

线程例程:

void *func_a (void *arg)
{      
    pthread_t thr_e;
    void *status;

    pthread_t tid = pthread_self();
    printf("[%2d] D: In thread D [%s]\n", my_time(), (char *)thread_name(tid));

    pthread_cleanup_push(cleanup, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    //sleep(1);
    pthread_create(&thr_e, &attr, func_e, NULL);
    printf("[%2d] D: Created thread E [%s]\n", my_time(), (char *)thread_name(thr_e));
    sleep(20);
    printf("[%2d] D: Thread exiting...\n", my_time());
    pthread_cleanup_pop(0);
    return (void *)55;
}

清理程序:

void
cleanup (void *arg)
{
    printf("[%2d] Calling cleanup...\n", my_time());
}

主线程例程:

int main()
{
    ......
    printf("[%2d] Main: Created thread C [%s]\n", my_time(),
               (char *)thread_name(thr_c));
    //sleep(20);
    printf("[%2d] Main: Cancelling Thread D\n", my_time());
    error1 = pthread_cancel(thr_d);
    //sleep(1);
    printf("[%2d] Main: Calcel status %d, %s, %d\n",
               my_time(), error1, (char *)strerror(errno), (int)thr_d);
    printf("[%2d] Main; Exiting...\n", my_time());
}

输出如下:

    [ 0] Main: Calcel status 0, Success, -1218630848
    [ 0] Main; Exiting...
    [ 0] Calling cleanup...

那么为什么要调用cleanup()? 请让我知道这里发生了什么。

1 个答案:

答案 0 :(得分:0)

由于未打印“D:Thread exiting”,因此可以假设主线程在推送和弹出之间取消D(在示例代码中的睡眠期间)。这导致执行尚未弹出的清理。

根据man page(强调补充):

  1. 当一个线程被取消时,所有堆叠的清理处理程序都会按照它们被推入堆栈的顺序反向弹出并执行