如何暂停使用者,直到以无锁方式生成对象



我有两个线程,一个生产者和一个消费者。

制片人可能并不总是在生产一些东西。然而,消费者需要在它可用时立即消费它。

生产者线程在循环中工作并将结果放入ConcurrentQueue中。使用者线程处于while (!disposing)循环中,当系统禁用时调用AutoResetEvent.WaitOne。我也考虑过在 ConcurrentQueue.TryDequeue 方法返回 false 的情况下调用AutoResetEvent.WaitOne;仅当队列中没有剩余项目时,才会发生这种情况。

但是,如果我要这样做,则在完成以下执行时可能会发生死锁:

  1. 排队
  2. TryDequeue 返回 true
  3. 尝试取消排队返回假
  4. 排队
  5. 等一

这是此代码片段中的可能性:

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);
}

不使用锁的正确方法是什么?

我认为在这里使用BlockingCollection会很好。它将有效地等待,直到队列中有数据。我认为你可以把它与ConcurrentQueue结合起来。请参阅 http://msdn.microsoft.com/en-us/library/dd267312.aspx

这里的问题是线程暂停在几乎所有操作系统中都是内核级事件。 我认为使用Fibers的Windows允许用户级别的暂停/取消暂停,但这就是我所知道的。

所以你无锁地随着你的队列呼啸而过,但是当队列中首先有东西时,你如何发出信号?

信号意味着睡觉——这就是问题所在。 你可以做无锁信令,但是等待,好吧,你必须调用WaitForEvent()的操作系统等效物,这是一个问题,因为你不想使用这些缓慢的操作系统提供的机制。

基本上,目前还没有或非常轻微的操作系统支持。

相关内容

  • 没有找到相关文章

最新更新