Does any deadlock occur in this code?

自闭症网瘾萝莉.ら 提交于 2019-12-24 08:53:24

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!