1

誰でもこのコードに少し光を当てることができますか? ステップバイステップの作業?私が理解していることは、コードのクリティカル セクションが一度に 1 つのスレッドによってアクセスされるようにロックされていることです。

lock (buf)
{
    buf.AddRange(ary);
    Monitor.Pulse(buf);
}

PS:MSDNはパルスを次のように説明しています

パルス(信号)、PulseAll

1 つ以上の待機中のスレッドにシグナルを送信します。シグナルは、ロックされたオブジェクトの状態が変化したこと、およびロックの所有者がロックを解放する準備ができていることを待機中のスレッドに通知します。待機中のスレッドは、最終的にオブジェクトのロックを受け取ることができるように、オブジェクトの準備完了キューに配置されます。スレッドがロックを取得すると、オブジェクトの新しい状態をチェックして、必要な状態に到達したかどうかを確認できます。

4

1 に答える 1

0

Monitor クラスは、ロック オブジェクトごとに 2 つのキュー (「準備完了」キューと「待機中」キュー) を維持します。

lock (buf)

現在のスレッドは、「buf」の Ready キューの後ろに配置され、ロックを取得する順番を待ちます。

buf を使用する他のスレッドがあり、そのうちの少なくとも 1 つが呼び出されていると仮定する必要があります。

Monitor.Wait(buf);

その後、Monitor はその別のスレッドを buf の Waiting キューに配置し、そこでスタックします。

これで、現在のスレッドがロックを取得すると、実行が続行されます。

Monitor.Pulse(buf);

これは Monitor に、Waiting キューの先頭にあるスレッドを取得し、それを Ready キューの末尾に移動するように通知します。Waiting キューでスタックしていた別のスレッドは、buf のロックの順番を取得するために並んでいます。

ロック ブロックの最後に、Monitor.Exit が自動的に呼び出され、現在のスレッドは buf の Ready または Waiting キューになくなります。

残りのコードを見ずに、lock ステートメントで Monitor.Pulse 呼び出しが必要な理由を説明することは不可能です。

編集

何が起こっているかについての私の推測は次のとおりです。これはプロデューサー/コンシューマー キュー パターンの実装である可能性があります。

コンシューマー スレッドが buf を見て、消費できるアイテムがないことを確認すると、Monitor.Wait(buf) を呼び出し、消費する新しいアイテムがあることが通知されるまで待機キューに留まります。

表示しているコードは、プロデューサー スレッドがアイテムを buf に追加するときのものです。次に、Monitor.Pulse(buf) を呼び出してコンシューマ スレッドの 1 つをウェイクアップし、そのコンシューマ スレッドを Ready キューに移動して、buf のロックを待ちます。

于 2013-03-04T13:55:40.330 に答える