web-dev-qa-db-ja.com

pthreadの場合、メインスレッドから子スレッドを強制終了する方法

Pthread_createを使用して、複数の子スレッドを作成します。一度に、メインスレッドがすべての子スレッドを強制終了するか、セグメントフォールトが発生します。それを完了するには、どの関数を使用する必要がありますか?私はグーグルから答えを検索し、pthread_killのような機能を得ました。しかし、それらを殺すために子スレッドにどのシグナルを送るべきかは知りませんでした。私の実行環境はRHEL 5.4で、プログラミング言語はCです。

19
terry

pthread_cancel を使用してスレッドを「キャンセル」することができます。ただし、これは通常、ベストプラクティスではありませんが、SEGFAULTのような極端な状況では合理的なアプローチと見なされる可能性があります。

21
torak

一般に、子スレッドを激しく殺したくはありませんが、代わりに終了するように要求します。そうすれば、子供が安全な場所で辞めており、そのすべてのリソースがクリーンアップされていることを確認できます。

私は通常、親と子の間の共有状態の小さな部分でこれを行い、親が各子に「終了要求」を伝達できるようにします。これは、ミューテックスによって保護された、各子のブール値にすることができます。子はこの値を定期的にチェックします(ループの繰り返しごと、または子スレッドにある便利なチェックポイント)。 「quit_request」がtrueになると、子スレッドはクリーンアップし、pthread_exitを呼び出します。

親側では、「kill_child」ルーチンは次のようになります。

acquire shared mutex
set quit_request to true 
pthread_join the child 

子が終了要求をチェックする頻度によっては、pthread_joinに時間がかかる場合があります。遅延が何であれ、デザインで処理できることを確認してください。

25
Bill Gribble

使用して、SIG_TERMを各スレッドに送信する必要があります

  int pthread_kill(pthread_t thread, int sig);

(メイン以外の)すべてのスレッドを削除する簡単な方法は、fork()して、子を使用し続けることです。
ハイパークリーンではありません...

  if (fork()) exit(0); // deals also with -1...
7
Ring Ø

プログラム全体にグローバル変数を使用できます。

int _fCloseThreads;

スレッドの実行を終了する場合、1に設定します。スレッドに「ループ」内のその変数をチェックさせ、1に設定されたときにうまく終了させます。ミューテックスで保護する必要はありません。

スレッドが終了するまで待つ必要があります。結合を使用できます。別の方法は、スレッドがスレッドprocに入るときにカウンタをインクリメントし、終了するときにカウンタをデクリメントすることです。カウンターはグローバルな種類である必要があります。カウンターでgcc atomic opsを使用します。メインスレッドは、fCloseThreadsを設定した後、カウントをループ、スリープ、およびチェックすることにより、カウンターがゼロになるのを待つことができます。

最後に、pthread_cleanup_Pushをチェックアウトしてポップします。これらは、スレッドがコード内のどこでもキャンセル(ロングジャンプを使用)し、threadprocを終了する前に最終的なクリーンアップ関数を呼び出すことができるようにするためのモデルです。基本的に、cleanup_Pushをthreadprocの上部に、cleanup_popを下部に配置し、アンワインド関数を作成します。その後、特定のキャンセルポイントで、pthread_cancel()の呼び出しによってキャンセルされたスレッドがthreadprocにロングジャンプしてアンワインド関数を呼び出します。

3
johnnycrash