0

pthread_cleanup_popのマニュアルページによると、この関数の引数がゼロ以外の場合はクリーンアップハンドラーが呼び出されます。それ以外の場合は、一致するpthread_cleanup_pushによってインストールされたクリーンアップハンドラーから削除されます。

私はUbuntu3.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」が出力されないため、メイン スレッドがプッシュとポップの間 (サンプル コードのスリープ中) に D をキャンセルしたと見なすことができます。これにより、まだポップされていないクリーンアップが実行されます。

manページによると(強調を追加):

  1. スレッドがキャンセルされると、スタックされたすべてのクリーンアップ ハンドラーがポップされ、スタックにプッシュされた順序とは逆の順序で実行されます。
于 2012-10-27T14:23:58.097 に答える