سؤال

I have two threads, a producer and a consumer.

The producer might not always be producing something. The consumer however, needs to consume it as soon as it becomes available.

The producer thread works in a loop and puts results into a ConcurrentQueue. The consumer thread is in a while (!disposing) loop that calls AutoResetEvent.WaitOne when the system becomes disabled. I've considered calling AutoResetEvent.WaitOne also in the case when the ConcurrentQueue.TryDequeue method returns false; this should only ever happen when there are no items left in the queue.

However, if I were to do this, a deadlock could occur when the following execution is done:

  1. Enqueue
  2. TryDequeue returns true
  3. TryDequeue returns false
  4. Enqueue
  5. WaitOne

This is a possibility in this snippet:

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

What is the proper way to do this without using locks?

هل كانت مفيدة؟

المحلول

I think the BlockingCollection would be good to use here. It will wait efficiently until there is data in the queue. You can combine this with a ConcurrentQueue I think. See http://msdn.microsoft.com/en-us/library/dd267312.aspx

نصائح أخرى

The problem here is that thread pausing is in almost all operating systems a kernel level event. Windows I think with Fibers permits user-level pausing/unpausing, but that's all I know of.

So you locklessly whizz along with your queue, but how do you signal when there is something in the queue in the first place?

Signalling implies sleeping - and that's the problem. You can do lock-free signalling, but waiting, well, you gotta call the OS equivelent of WaitForEvent(), and that's a problem, because you don't WANT to be using these slow, OS provided mechanisms.

Basically, there's no or very litle OS support for this yet.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top