0

次の (疑似) コードは、私が理解できない動作を引き起こします。2 つのスレッドが並行して実行されています。どちらも同じ (複雑な) 計算を行いますが、どちらが先に終了するかはわかりません。繰り返し実行すると、前者の方が早い場合と後者の方が早い場合があります。これは問題なく、意図したとおりに機能します。次に、最初に成功したスレッドが他のスレッドを終了し、両方が一緒に分岐する必要があります。ただし、最初のソルバーが終了するとすべてがうまくいきますが、2 番目のソルバーが最初に終了すると、「結合コマンド」は最初のソルバーが終了したことを認識しません (そのため、結合は永久に待機し、プログラムは続行されません)。私が間違っていたことや、何が違うのか考えてみませんか?

void* thread_function(...)
{
   do_some_complex_task();
   if (successfull && first_finsihed)
   {
        pthread_chancel(other_thread);
   }
}

int main()
{
    std::vector<pthread_t*> store;
    store.resize(2);

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    pthread_create(store[0], NULL, thread_function, ...);
    pthread_create(store[1], NULL, thread_function, ...);

    pthread_join(*store[0], NULL);
    pthread_join(*store[1], NULL);
}

PS。疑似コードの詳細が不十分な場合はお知らせください。

4

2 に答える 2

1

疑似コードに基づくと、1 つの問題として、スレッドが非同期キャンセルではなく据え置きキャンセル (デフォルト値) を使用している可能性があります。キャンセルされたスレッドがキャンセル ポイントに到達しない場合は、pthread_joinブロックされます。を呼び出すpthread_createと、新しく作成されたスレッドは呼び出し元のスレッドの以下を継承します。

pthread_setcanceltypeキャンセルしたいスレッド内から呼び出してみてください。スレッドの現在の状態を識別するために、デバッガーをプログラムに接続することを検討することもできます。

理想的には、可能であれば避けることを検討してpthread_cancelください。pthread 呼び出しは文書化されていますが、すべての細部が細かいため、正確な動作を取得して維持することは困難な場合があります。一般に、スレッドが終了するように設定されていることを示すフラグを設定し、設定されたときに関数から戻り始める方が簡単です。ではdo_some_complex_task、複雑なタスクを小さなタスクに分割することを検討し、各小さなタスク間のキャンセルを確認してください。

于 2012-07-03T14:26:57.543 に答える
1

使用しないでくださいpthread_cancel - グローバル状態を使用し、各スレッドの「メイン ループ」内でチェックします。スレッドの関数が終了する直前に「オン」に設定します。

于 2012-07-03T12:15:25.983 に答える