遅延キャンセルポイントを使用することができます。スレッドでは、pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);
を使用します(これがデフォルトですが、明示的になることはありません)。 pthread_setcancelstate
でキャンセルを無効にします。ただし、条件変数を超えてキャンセル可能になるまで待ってください。キャンセル清掃ハンドラを設定するにはpthread_cleanup_push
を使用してください。これはRAIIでうまく再生されません。
これでスレッドをpthread_cancelできるようになりました。取り消しクリーンアップハンドラが実行され、登録の逆の順序で、TLSデータデストラクタが呼び出され、スレッドが終了します(条件変数waitから戻ることはありません)。
もちろん、これはかなり醜いデザインです。理想的にはデッドロックを避けるべきです。それが不可能な場合は、私の場合は、一度に1つのcvarでブロックするスレッドを1つだけ手配し、複数のCvarを処理するためにこれらのcvarsに基づいてより高いレベルの明示的なウェイターリストを構築しますウェイターは、依然として個々にアドレス可能なスレッドを可能にします。
確率が1に非常に近い場合、デザインに欠陥があります。ほとんどの場合、「デッドロックを検出して、それに参加しているスレッドの1つを殺す」ことはほとんどありません。デッドロックが起こらないように基本的なデザインを修正したいのですが... – Nemo
@Nemo ...私はあなたに同意します。しかし、デッドロックが発生する可能性は極めて低いため、具体的には、デッドロックを検出して解決するのではなく、回避することを選択します。 –
申し訳ありません@ジャグラー、私はその哲学を購入していません。これはソフトウェアです。 「非常にまれ」というものはありません。 「決して」と「バギー」しかありません。あるいはヨーダが言うように、試行はありません。 – Nemo