1

現在、メイン スレッドが 3 つの子スレッドを作成するプログラムを作成しています。これらのスレッドは同時に実行されています。私がやりたいことは、子スレッドの 1 つが完了したら、出力が正しいかどうかを確認することです。そうである場合は、他の 2 つのスレッドを終了します。そうでない場合は、このスレッドの結果を破棄し、他の 2 つのスレッドの結果を待ちます。

pthread_create を使用して、メイン関数で 3 つの結果を作成しています。しかし、結合機能の使い方がわかりません。メイン関数で join 関数を 3 回使用すると、3 つのスレッドが完了するまで 1 つずつ待機します。

私の計画は次のとおりです。

int return_value;

main(){
    pthread_create(&pid[0], NULL, fun0, NULL);
    pthread_create(&pid[1], NULL, fun1, NULL);
    pthread_create(&pid[2], NULL, fun2, NULL);

}

fun0(){
    ...
    if( check the result is right ){
      return_value = result;
      if (pid[1] is running)  pthread_kill( pid[1], SIGTERM );
      if (pid[2] is running)  pthread_kill( pid[2], SIGTERM );
    }

fun1() ...
fun2() ...

関数 0、1、および 2 は互いに類似しており、1 つの関数が正しい答えを持つと、他の 2 つのスレッドが強制終了されます。ただし、プログラムの実行中に pthread_kill が処理されると、1 つのスレッドだけでなく、プログラム全体が終了します。どうしてか分かりません。

そして、このプログラムをコーディングする他の方法があるかどうかはまだわかりません。これから私を助けてくれてありがとう。

4

1 に答える 1

5

このpthread_kill()関数は、kill()プロセスを終了するように設計されていないのと同様に、スレッドを終了するようには設計されていません。これらの関数はシグナルを送るだけであり、それらの名前は不幸な歴史の副産物です。特定のシグナル ハンドラは、プロセスを終了させます。を使用pthread_kill()すると、どのスレッドがシグナルを処理するかを選択できますが、シグナル ハンドラーはまったく同じことを行います (たとえば、プロセスを終了します)。

スレッドを終了するには、 を使用しますpthread_cancel()。これにより、通常、次のキャンセル ポイントでスレッドが終了します。キャンセル ポイントは、 のマニュアル ページに記載されています。 、、pthread_cancel()などの特定の機能のみがキャンセル ポイントです。write()sleep()pthread_testcancel()

ただし、スレッドのキャンセル可能タイプ ( pthread_setcanceltype()) をPTHREAD_CANCEL_ASYNCHRONOUSに設定すると、いつでもスレッドをキャンセルできます。これは危険な場合があり、細心の注意を払う必要があります。たとえば、malloc()通話中にスレッドをキャンセルすると、後であらゆる種類の厄介な問題が発生します。

おそらく、共有変数を時々テストするか、またはkill()必要がなくなった場合にのみ使用できる別のプロセスを使用する方がはるかに簡単であることに気付くでしょう。スレッドのキャンセルはトリッキーです。

概要

  1. 最も簡単なオプションは、各スレッドで変数をテストして、キャンセルする必要があるかどうかを確認することです。

  2. これが機能しない場合、次の推奨事項はfork()の代わりにを使用することです。pthread_create()その後、 を使用できますkill()

  3. 火遊びをしたい場合は、非同期を使用してくださいpthread_cancel()。これはおそらくあなたの顔で爆発します。バグを探したり、クリーンアップを正しく行う方法を見つけようとして、貴重な時間を何時間も費やさなければなりません。あなたは睡眠を失い、あなたの猫はネグレクトで死んでしまいます。

于 2013-06-10T00:51:10.380 に答える