1

従来のプロデューサー/コンシューマー スレッドの例を考えてみましょう。コンシューマがバッファ サイズがゼロでないことを確認する場合、ロックを待機する前に他のスレッドに通知する必要はありますか? メソッドコードは次のとおりです。

public void consume()
{
    lock(_lock)
    {
        while(buf.Count == 0)
        {
             // Is there any need to *Monitor.Pulse(_lock);* here?
             Monitor.Wait(_lock);
        }
        // Consume
    }
}

public void produce()
{
    lock(_lock)
    {
        // Produce
        buf.Insert(item);
        Monitor.PulseAll(_lock);
    }
}
4

1 に答える 1

2

いいえ、それはデッドロックしません:

  • プロデューサーがロックを取得できると、すぐに解放します (パルスはプロデューサーを中断しません)。
  • コンシューマーがロックを取得できると、データを見つけるか、適切に待機します (ロックを解放します)。

プロデューサが取得できないロックを待機するシナリオはありません。しかし、私は、PulseAll消費者の中で明確な目的を果たさないと言いたい. 他の質問に答えるには:

ロックを待機する前に他のスレッドに通知する必要はありますか

実際、そうするのは非常に悪い考えです。これを行うと、2 つのコンシューマがお互いに永遠に目を覚まし続ける可能性があるためです。

パルスが役立つのは、誰かが待っていると信じる理由があり、何かを実行できるときだけです。バッファが以前に空だった場合(つまり) 、実際にはパルスのみに減らすことができます。空でない場合は、おそらく誰も待っていないからです。if(buf.Count == 1)

于 2013-10-01T11:25:06.757 に答える