1

私は c++ をブースト スレッド、ロック ミューテックスなどの優れた機能と共に使用しています。

2 つのスレッド A と B。A は、クライアントから情報がやり取りされるネットワーク スレッドです。B は、スレッドセーフである必要がある変数を持つワーカーです。

クラス A には複数のスレッドがあり、B は単一のスレッドです。A のインスタンスは B のジョブ リストに追加され、B がタスクを完了するまで A はロックされます。(ジョブのスレッドセーフリストは正常に機能します)

A は B にジョブを追加してからロックしますが、ほとんどの場合、A がロックする前です。B はジョブを処理し、A がロックを適用する前にロックを解除 (しようと) します。その結果、As デッド ロックが発生します。

ここで何をすべきかわかりません。コードを投稿することはできますが、概念的に議論する方が簡単だと思います。

4

2 に答える 2

1

条件を使用する必要がある場所でロックを使用しているようです。ブーストドキュメントの引用:

クラスcondition_variableとクラスcondition_variable_anyは、特定の条件が true になったという別のスレッドからの通知を 1 つのスレッドが待機するメカニズムを提供します。

それはあなたがロックでやろうとしていることのように聞こえます。

于 2012-09-01T13:14:47.877 に答える
1

実際の問題は、B がタスクを取得し、A からのスレッドがロックする前にそのタスクの実行を開始することです。オブザーバーの結果は、「通知の見逃し」として分類できます。ミューテックスやその他の単純なシンクロナイザなどを使用して双方向同期を実装しようとすると、非常に頻繁に発生します。

Aがすでに待機していない限り、Bが通知しないようにするか、通知を見逃さないようにする必要があります。

最初の方法は実行するのが非常に難しいかもしれませんが、後者は非常に簡単です: セマフォ (または手動リセットイベントまたは (...)) を使用します。

セマフォ:

  • スレッド A がジョブをキューに入れたい
  • スレッド A は、COUNT=ZERO および MAX=1 でセマフォを作成します
  • スレッド A は何らかの形でセマフォをジョブに追加します
  • スレッド A がジョブをキューに入れる
  • スレッド A はセマフォで待機します
  • スレッド A がセマフォを破棄する

その間:

  • スレッド B はキューを監視します
  • スレッド B がタスクを取得します
  • スレッド B がジョブを実行する
  • スレッド B はセマフォを一度ロック解除します

count の場合、セマフォ UNLOCK はノンブロッキングであることに注意してください。

セマフォを使用する代わりに、手動でセット/リセットするイベントも使用できます。A が OFF のイベントを作成してロックし、B がそれを ON に設定するだけです。

于 2012-09-01T13:18:46.033 に答える