ノンブロッキング pthread_join
-
09-06-2019 - |
質問
マルチスレッドサーバーのシャットダウンをコーディングしています。すべてが順調に進むと、すべてのスレッドが独自に終了しますが、スレッドがスタックする可能性がわずかにあります。この場合、ノンブロッキング結合があると便利です。だから私にはできました。
ノンブロッキングの pthread_join を実行する方法はありますか?ある種の時間指定の参加も良いでしょう。
このようなもの:
foreach thread do nb_pthread_join(); if still running pthread_cancel();
非ブロック結合が役立つケースはもっとたくさんあると思います。
そのような関数はないようなので、すでに回避策をコーディングしましたが、それは私が望むほど単純ではありません。
解決
他の人が指摘しているように、標準の 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 を呼び出すとブロックされず、スレッドの終了 (クリーンかどうかに関係なく) が保証されます。
これは「簡単な」回避策として認められるはずです。
他のヒント
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 拡張機能ではありませんが、便利です。
「pthread_join」メカニズムは、まさに必要な動作を行う場合に使用すると便利です。自分で実行できないことは何もありません。また、望んでいることとまったく異なる場合は、望むとおりにコードを記述します。
スレッドが終了したかどうかを実際に気にする必要がある本当の理由はありません。重要なのは、スレッドが行っていた作業が完了したかどうかです。それを伝えるには、スレッドに、スレッドが機能していることを示す何らかの処理を行わせます。それを行う方法は、特定の問題にとって何が理想的であるかによって決まり、それはスレッドが何を実行しているかに大きく依存します。
まずは考え方を変えることから始めましょう。スレッドがスタックするのではなく、スレッドが実行していた内容がスタックします。
QNX 用に開発している場合は、pthread_timedjoin() 関数を使用できます。
それ以外の場合は、pthread_join() を実行し、子スレッドが完了したことをセマフォなどに通知して親スレッドに警告する別のスレッドを作成できます。この別個のスレッドは pthread_join() から取得したものを返すことができるため、親スレッドは子がいつ完了するかだけでなく、どのような値を返すかを決定できます。
答えは実際に、なぜこれを行いたいのかによって異なります。たとえば、死んだスレッドをクリーンアップしたいだけの場合は、ループして結合する「死んだスレッド クリーナー」スレッドを用意するのがおそらく最も簡単です。
正確に何を言いたいのかはわかりませんが、本当に必要なのは待機と通知のメカニズムだと思います。
簡単に言うと、その仕組みは次のとおりです。タイムアウトして条件が満たされるまで待機します。次の場合、待ち時間は終了します。
- タイムアウトが発生したり、
- 条件が満たされている場合。
これをループに含めて、ロジックにさらにインテリジェンスを追加できます。Pthreads に関連するこれについて私が見つけた最良のリソースは、このチュートリアルです。POSIX スレッド プログラミング (https://computing.llnl.gov/tutorials/pthreads/).
また、Pthread に時間指定結合用の API がないことにも非常に驚きました。
時間制限はありません pthread_join
, ただし、条件に基づいてブロックされる他のスレッドを待っている場合は、timed を使用できます。 pthread_cond_timed_wait
の代わりに pthread_cond_wait
ノンブロッキングとしてオープンされたパイプにバイトをプッシュして、完了時に他のスレッドに通知し、ノンブロッキング読み取りを使用してパイプのステータスをチェックできます。