问题
Consider traditional producer/consumer threading example. When consumer checks for buffer size not to be zero, is there any need to signal other threads before waiting on lock? Here is methods code:
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);
}
}
回答1:
No, that won't deadlock:
- once the producer can get the lock, it releases it promptly (the pulse doesn't interrupt the producer)
- once the consumer can get the lock, it either finds data, or it waits (releasing the lock) appropriately
There is no scenario where the producer ends up waiting on an unobtainable lock. I would, however, say that the PulseAll
in the consumer serves no obvious purpose. To answer your other question:
is there any need to signal other threads before waiting on lock
None whatsoever, and in fact it would be a very bad idea to do so. Because if you did this, two consumers could keep waking each-other up forever, even though there is no useful work to do.
The only time it is useful to pulse is when you have reason to believe that someone is waiting, and can now do something. You could actually probably reduce it to only pulse if the buffer was previously empty (i.e. if(buf.Count == 1)
) - because if it wasn't empty, presumably nobody is waiting.
来源:https://stackoverflow.com/questions/19114831/does-any-deadlock-occur-in-this-code