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在消费者中没有明显的目的。要回答您的另一个问题:

在等待锁定之前是否需要向其他线程发出信号

无论如何都没有,事实上这样做是一个非常糟糕的主意。因为如果你这样做了,即使没有有用的工作要做,两个消费者也可以永远互相唤醒。

脉搏唯一有用的时候是当你有理由相信有人在等待并且现在可以做某事时。如果缓冲区先前为空(即),您实际上if(buf.Count == 1)可以将其减少为仅脉冲- 因为如果它不是空的,大概没有人在等待。

于 2013-10-01T11:25:06.757 回答