我有两个主题,一个制作人和一个消费者。
制作人可能并不总是在制作某些东西。然而,消费者需要尽快消费它。
生产者线程在循环中工作并将结果放入ConcurrentQueue
。消费者线程位于while (!disposing)
循环中,当系统被禁用时调用AutoResetEvent.WaitOne
。在AutoResetEvent.WaitOne
方法返回false的情况下,我也考虑过调用ConcurrentQueue.TryDequeue
;只有在队列中没有剩余项目时才会发生这种情况。
但是,如果我这样做,则在执行以下执行时可能会发生死锁:
这个代码段中有可能:
while (this.isDisposing == 0)
{
if (this.isEnabled == 0)
{
this.signal.WaitOne();
}
object item;
if (!this.queue.TryDequeue(out item))
{
this.signal.WaitOne();
continue;
}
this.HandleItem(item);
}
在不使用锁的情况下执行此操作的正确方法是什么?
答案 0 :(得分:1)
我认为BlockingCollection在这里很好用。它将有效等待,直到队列中有数据。您可以将它与ConcurrentQueue结合起来。见http://msdn.microsoft.com/en-us/library/dd267312.aspx
答案 1 :(得分:0)
这里的问题是,线程暂停在几乎所有操作系统中都是内核级事件。我认为使用Fibers的Windows允许用户级暂停/取消暂停,但这是我所知道的。
所以你无人随意地跟着你的队列一起,但是当你的队列中有什么东西时你怎么发出信号呢?
信号意味着睡觉 - 这就是问题所在。你可以做无锁信号,但等等,好吧,你必须调用等同于WaitForEvent()的操作系统,这是一个问题,因为你不想使用这些缓慢的操作系统提供的机制。
基本上,目前还没有或非常适合的操作系统支持。