2011-08-03 12 views
0

この質問はBreaking a condition variable deadlockに続きます。いくつかのスレッドが条件変数を待っている可能性があります。スレッド1と言う特定のスレッドのみに信号を送り、デッドロックシナリオの参加者だったので、それを強制終了する必要があります。私がたくさんの部分糸だけを伝える方法がありますか?多くの状況変数の中で特定のスレッドにシグナルを送る

は、いくつかの助けのために

おかげ

編集gratefullだろう。 Nemoのコメントを尊重する。これは悪い考えです。しかし、それを行う方法はありますか?

+4

確率が1に非常に近い場合、デザインに欠陥があります。ほとんどの場合、「デッドロックを検出して、それに参加しているスレッドの1つを殺す」ことはほとんどありません。デッドロックが起こらないように基本的なデザインを修正したいのですが... – Nemo

+0

@Nemo ...私はあなたに同意します。しかし、デッドロックが発生する可能性は極めて低いため、具体的には、デッドロックを検出して解決するのではなく、回避することを選択します。 –

+1

申し訳ありません@ジャグラー、私はその哲学を購入していません。これはソフトウェアです。 「非常にまれ」というものはありません。 「決して」と「バギー」しかありません。あるいはヨーダが言うように、試行はありません。 – Nemo

答えて

1

遅延キャンセルポイントを使用することができます。スレッドでは、pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);を使用します(これがデフォルトですが、明示的になることはありません)。 pthread_setcancelstateでキャンセルを無効にします。ただし、条件変数を超えてキャンセル可能になるまで待ってください。キャンセル清掃ハンドラを設定するにはpthread_cleanup_pushを使用してください。これはRAIIでうまく再生されません。

これでスレッドをpthread_cancelできるようになりました。取り消しクリーンアップハンドラが実行され、登録の逆の順序で、TLSデータデストラクタが呼び出され、スレッドが終了します(条件変数waitから戻ることはありません)。

もちろん、これはかなり醜いデザインです。理想的にはデッドロックを避けるべきです。それが不可能な場合は、私の場合は、一度に1つのcvarでブロックするスレッドを1つだけ手配し、複数のCvarを処理するためにこれらのcvarsに基づいてより高いレベルの明示的なウェイターリストを構築しますウェイターは、依然として個々にアドレス可能なスレッドを可能にします。

+0

これについて少し詳しく説明できますか?キャンセルを有効にして条件変数を待つ間に基本的な競合条件はありませんか?つまり、あなたはミューテックスを保持し、取り消しを有効にしてから、cond varを待つことを試みます...しかし、その間に誰かがあなたにミューテックスを保持している間にあなたがデッドロックして核を奪うと決めますか? – Nemo

+0

@Nemo、pthread_cond_waitのマンページから: "条件待ち(時間切れかどうか)は取り消しポイントです。スレッドのキャンセル可能状態がPTHREAD_CANCEL_DEFERREDに設定されている場合、条件待ちの間にキャンセル要求に作用する副作用は、最初のキャンセルクリーンアップハンドラを呼び出す前にmutexが(実際に)再取得されることです。クリーンアップハンドラはミューテックスを解放する必要があります。 – bdonlan

0

あなたが必要とするものを正確に行うためのコードを書いてください。条件変数はこの動作を提供しないため、ショートカットはありません。だからそれを書いてください。それについて何も難しいことはありません。たとえば、特別なフラグを設定し、条件変数でブロックされたすべてのスレッドを復帰させ、フラグをチェックしてスリープ状態に戻るかどうかを確認するスレッドをコーディングすることができます。