线程切换和死锁预防问题

如果有两个线程作为生产者/消费者,最好有以下行来防止死锁。我知道实时锁定但是假设它们在调用Wait()方法之前做了很多工作:
// member variable
object _syncLock = new object();

void Wait()
{
   lock (_syncLock)
      {
         Monitor.Pulse(_syncLock);
         Monitor.Wait(_syncLock);
      }
}
这两个线程都不可能处于等待状态。     
已邀请:
这似乎过于复杂。只需首先正确处理锁定,避免出现问题。如果你只有两个线程,并且他们试图获得相同的单锁(正确),那么你不应该有死锁。死锁意味着此处还有其他事情发生。 话虽这么说,如果您可以选择通过.NET 4(或.NET 3.5上的Rx扩展)使用TPL,您可能需要考虑使用
BlockingCollection<T>
。它非常适合在生产者/消费者场景中使用,并以无锁方式工作。     
如果您的目的是创建生产者 - 消费者模式的配对变体,那么生产者的序列为
Wait
,生产者为
Wait
,消费者为
Wait
之前的序列为
Wait
。你可以在Joe Duffy的文章中参考图5。 Howerver,请记住,由于他的实施在
Enqueue
方法中执行无条件的
Wait
,因此在生产者和消费者之间会产生类似乒乓的效果。在他的实现中,队列每个生产者只能有一个项目。所以,如果这是你的意图那么这是你的票。否则,您可以按原样调整它并将一些条件1应用于
Enqueue
方法中的
Wait
,使其更像一个真正的FIFO缓冲区。 然而,像里德一样,我质疑为什么不能使用
BlockingCollection
。这个集合应该非常高效,因为它使用了
Add
Take
方法的无锁策略。当然,就像我上面提到的那样,如果你真的想要配对变种,那么这个系列将无法满足你的要求,你将不得不使用Joe Duffy作为起点。 1在使用等待之前,请记住使用
while
循环而不是
if
检查。
Monitor.Wait
只是等待锁定状态的改变而已,仅此而你必须重新检查等待条件。     

要回复问题请先登录注册