web-dev-qa-db-ja.com

ノンブロッキングpthread_join

マルチスレッドサーバーのシャットダウンをコーディングしています。すべてが正常に実行された場合、すべてのスレッドが独自に終了しますが、スレッドがスタックする可能性はわずかです。この場合、非ブロッキング結合があると便利です。だから私はできた。

非ブロッキングpthread_joinを実行する方法はありますか?ある種の時限結合も良いでしょう。

このようなもの:

 foreach thread do 
 nb_pthread_join(); 
まだ実行中の場合
 pthread_cancel(); 

ブロークしない結合が役立つ場合がもっとあると思います。

そのような関数がないように思われるので、私はすでに回避策をコーディングしましたが、それは私が望むほど単純ではありません。

21
Figo

他の人が指摘しているように、標準のpthreadライブラリで利用できる非ブロッキングpthread_joinはありません。

ただし、述べた問題(プログラムのシャットダウン時にすべてのスレッドが終了することを保証しようとする)を考えると、そのような関数は必要ありません。あなたは簡単にこれを行うことができます:

int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
   int return = pthread_cancel(threads[i]);
   if(return != ESRCH)
      killed_threads++;
}
if(killed_threads)
    printf("%d threads did not shutdown properly\n", killed_threads)
else
    printf("All threads exited successfully");

すべてのスレッド(終了しているかどうか)でpthread_cancelを呼び出すことには何の問題もありません。したがって、すべてのスレッドに対してpthread_cancelを呼び出すと、ブロックされず、スレッドの終了(クリーンかどうか)が保証されます。

これは、「単純な」回避策と見なされます。

1
Frosty

Linuxでアプリケーションを実行している場合は、次のことを知りたいと思うかもしれません。

int pthread_tryjoin_np(pthread_t thread, void **retval);

int pthread_timedjoin_np(pthread_t thread, void **retval,
                                const struct timespec *abstime);

接尾辞が示すように、「np」は「非ポータブル」を意味するので注意してください。ただし、これらはPOSIX標準のgnu拡張機能ではありませんが、便利です。

マニュアルページへのリンク

22
yves Baumes

'pthread_join'メカニズムは、必要なことを正確に実行する場合に使用すると便利です。それはあなたが自分でできないことは何もしません、そしてそれがあなたが望むものと正確に一致しない場合、あなたが望むものを正確にコーディングします。

スレッドが終了したかどうかを実際に気にする必要がある本当の理由はありません。気になるのは、スレッドが行っていた作業が完了したかどうかです。それを伝えるために、スレッドにそれが機能していることを示すために何かをさせます。それをどのように行うかは、特定の問題に理想的なものに依存します。これは、スレッドが何をしているかに大きく依存します。

あなたの考えを変えることから始めてください。スタックするのはスレッドではなく、スレッドが行っていたことがスタックするのです。

10
David Schwartz

QNX向けに開発している場合は、pthread_timedjoin()関数を使用できます。

それ以外の場合は、pthread_join()を実行し、親スレッドに警告する別のスレッドを作成できます。たとえば、子スレッドが完了したことをセマフォに通知します。この個別のスレッドは、pthread_join()から取得したものを返すことができ、子がいつ完了するかだけでなく、どの値を返すかを親スレッドが決定できるようにします。

3
dmityugov

答えは本当にあなたがこれをしたい理由に依存します。たとえば、デッドスレッドをクリーンアップするだけの場合は、ループして結合する「デッドスレッドクリーナー」スレッドを用意するのがおそらく最も簡単です。

1
raldi

正確に何を意味するのかわかりませんが、本当に必要なのは待機と通知のメカニズムだと思います。

つまり、その仕組みは次のとおりです。条件がタイムアウトで満たされるのを待ちます。次の場合、待機は終了します。

  • タイムアウトが発生する、または
  • 条件が満たされている場合。

これをループに入れて、ロジックにインテリジェンスを追加することができます。 Pthreadsに関連して私が見つけた最高のリソースは、このチュートリアルです:POSIX Threads Programming( https://computing.llnl.gov/tutorials/pthreads/ )。

また、Pthreadに時限結合用のAPIがないことにも非常に驚いています。

1
Srikanth

時限pthread_joinはありませんが、条件でブロックされた他のスレッドを待っている場合は、pthread_cond_timed_waitの代わりに時限pthread_cond_waitを使用できます。

1
shodanex

非ブロッキングとして開かれたパイプにバイトをプッシュして、完了時に他のスレッドにシグナルを送信し、非ブロッキング読み取りを使用してパイプのステータスを確認できます。

0
Doug T.