pthread_join()
アプリケーションがシャットダウンしているため、呼び出しで簡単に再現できないSEGVをC ++で取得しています(10万回のテスト実行に約1回発生します) 。errnoの値を確認しましたが、ゼロです。これはCentosv4で実行されています。
どのような条件下pthread_join()
でSEGVを取得しますか?これは非常にまれであるため、ある種の競合状態である可能性があります。ある人は、pthread_detach()とpthread_exit()を呼び出すべきではないと提案していますが、その理由はわかりません。
私の最初の作業仮説は、他のスレッドで実行されpthread_join()
ている間に呼び出されpthread_exit()
、これが何らかの形でSEGVにつながるというものでしたが、多くの人がこれは問題ではないと述べています。
アプリケーションの終了時にメインスレッドでSEGVを取得する失敗したコードは、おおよそ次のようになります(簡潔にするためにエラーリターンコードのチェックは省略されています)。
// During application startup, this function is called to create the child thread:
return_val = pthread_create(&_threadId, &attr,
(void *(*)(void *))initialize,
(void *)this);
// Apparently this next line is the issue:
return_val = pthread_detach(_threadId);
// Later during exit the following code is executed in the main thread:
// This main thread waits for the child thread exit request to finish:
// Release condition so child thread will exit:
releaseCond(mtx(), startCond(), &startCount);
// Wait until the child thread is done exiting so we don't delete memory it is
// using while it is shutting down.
waitOnCond(mtx(), endCond(), &endCount, 0);
// The above wait completes at the point that the child thread is about
// to call pthread_exit().
// It is unspecified whether a thread that has exited but remains unjoined
// counts against {PTHREAD_THREADS_MAX}, hence we must do pthread_join() to
// avoid possibly leaking the threads we destroy.
pthread_join(_threadId, NULL); // SEGV in here!!!
releaseCond()
終了時に結合されている子スレッドは、メインスレッドで呼び出される上記のポイントから始まる次のコードを実行します。
// Wait for main thread to tell us to exit:
waitOnCond(mtx(), startCond(), &startCount);
// Tell the main thread we are done so it will do pthread_join():
releaseCond(mtx(), endCond(), &endCount);
// At this point the main thread could call pthread_join() while we
// call pthread_exit().
pthread_exit(NULL);
スレッドは正しく起動しているように見え、アプリケーションの起動時の作成中にエラーコードは生成されず、スレッドはタスクを正しく実行しました。これには、アプリケーションが終了するまでに約5秒かかりました。
このまれなSEGVが発生する原因と、それに対してどのように防御的にプログラムすることができるでしょうか。1つの主張は、pthread_detach()の呼び出しが問題であるということです。もしそうなら、コードをどのように修正する必要がありますか。