0

根据 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() 被调用呢?请让我知道这里发生了什么。

4

1 回答 1

0

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

根据手册页(强调添加):

  1. 当一个线程被取消时,所有堆叠的清理处理程序都被弹出按照它们被压入堆栈的相反顺序执行。
于 2012-10-27T14:23:58.097 回答