Click here to Skip to main content
13,501,608 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


31 bookmarked
Posted 11 Jul 2008

Producer Consumer Using Double Queues

, 11 Jul 2008
Rate this:
Please Sign up or sign in to vote.
Producer Consumer implementation using double queues


Producer consumer is an old computer science problem. Many solutions have been proposed to solve this problem. The general approach is using a common queue. A single queue to which the producer writes data to and the consumer reads data from. Avoiding race conditions is done by locking the queue so that when the producer is writing, the consumer is not reading and vice versa.

The problem with this approach is that whenever the producer puts data to the queue, it has to acquire a lock. Similarly whenever the consumer gets data, it has to lock the queue. This solution is inadequate on systems where the producer generates data in excess of a hundred thousand updates per second. In my opinion, a hundred thousand locks on the queue in one second is a huge performance penalty.


Once while going over this conundrum with my better half, I was introduced to the concept of double queuing. Something similar to the double buffering used in graphics applications to avoid flicker. As far as my research goes, I was not able to find a similar solution to the producer consumer problem. In case this is duplication, my apologies. I would be indebted if you can point me to the original work.

Double Queuing

The solution proposed is very simple and elegant. Instead of using a single queue, we use two queues. At a given time, one queue is designated write queue and the other, the read queue. This helps us to avoid locking the queue while reading and writing to it. The producer is free to fill the write queue and the consumer is free to empty the read queue.

When the consumer is done reading the read queue, the producer is blocked briefly and the queues are switched. Now the old read queue becomes the new write queue and the old write queue becomes the new read queue. After switching, if there is no data in the new read queue, the consumer is blocked. When the producer gets more data, it unblocks the consumer.

The Code

This solution makes use of Events for synchronization between the consumer and the producer. The producer code looks like this:

public void ProducerFunc()
    int data = 0;

    for (int i = 0; i < 10000; i++)
        data += 1;
        Thread.Sleep(m_Random.Next(0, 2));

private void MessageHandler(int data)

    m_ProducerData.WriteLine(data); // logging


The ProducerFunc() is a thread function that is invoked 10,000 times. Every time MessageHandler() is called, it checks to see if it has been blocked by the consumer. If not, it resets the ManualResetEvent to indicate to the consumer that the producer has not yet finished. This is useful when the consumer is trying to switch the queues and wants to know if the producer is finished writing to the queue. The rest of the code is straight forward. Data is written to queue and an event is set to wake up the consumer incase it was blocked. Finally, an event is set to indicate that the producer is finished writing to queue.

This is the consumer code:

public void ConsumerFunc()
    int count;
    int data;
    Queue<int> readQueue;

    while (true)

        m_UnblockHandlerEvent.Reset(); // block the producer
        m_HandlerFinishedEvent.WaitOne(); // wait for the producer to finish
        readQueue = m_CurrentWriteQueue;
        // switch the write queue
        m_CurrentWriteQueue = (m_CurrentWriteQueue == m_Q1) ? m_Q2 : m_Q1; 
        m_UnblockHandlerEvent.Set(); // unblock the producer

        count = 0;
        while (readQueue.Count > 0)
            count += 1;

            data = readQueue.Dequeue();
            m_ConsumerData.WriteLine(data); // logging

            Thread.Sleep(m_Random.Next(0, 2));
        Console.WriteLine("Removed {0} items from queue: {1}", 
                    count, readQueue.GetHashCode());

The ConsumerFunc() is a separate thread function. When the function starts, it checks to see if the data present event has been set. If not, then it is blocked till we get data written by the producer. Once data is present in the queue, the consumer resets the event to block the producer and waits for the producer to finish. The current write queue is now cached for reading and the current write queue is switched. After the queue is switched, the producer is unblocked to enable it to start writing to the new write queue. Meanwhile the consumer is busy reading from the read queue. Once the queue is empty, the entire process is repeated.

Points of Interest

On further discussing this solution with others, I was told using synchronization events causes more performance problems than using lock. What do you think about that argument? Can you shed some light on this from your experiences with lock and synchronization events?


  • 07/09/2008: First published


This article, along with any associated source code and files, is licensed under The zlib/libpng License


About the Author

Rammohan Raja
United States United States
Nothing to brag about, just another passionate software developer.

Work to make a living, don't live to work!

You may also be interested in...


Comments and Discussions

GeneralBetter solution Pin
federico.strati15-Sep-10 4:26
memberfederico.strati15-Sep-10 4:26 
GeneralRe: Better solution Pin
Raghavan Ram Raja15-Sep-10 5:44
memberRaghavan Ram Raja15-Sep-10 5:44 
GeneralRe: Better solution Pin
federico.strati15-Sep-10 6:20
memberfederico.strati15-Sep-10 6:20 
GeneralRe: Better solution Pin
Deusiro17-Sep-10 11:56
memberDeusiro17-Sep-10 11:56 
GeneralRe: Better solution Pin
federico.strati17-Sep-10 21:38
memberfederico.strati17-Sep-10 21:38 
GeneralRe: Better solution Pin
Deusiro18-Sep-10 13:04
memberDeusiro18-Sep-10 13:04 
GeneralRe: Better solution Pin
federico.strati18-Sep-10 21:09
memberfederico.strati18-Sep-10 21:09 
GeneralRe: Better solution [modified] Pin
Deusiro21-Sep-10 5:58
memberDeusiro21-Sep-10 5:58 
GeneralRe: Better solution Pin
federico.strati21-Sep-10 21:05
memberfederico.strati21-Sep-10 21:05 
GeneralRe: Better solution Pin
Raghavan Ram Raja22-Sep-10 3:35
memberRaghavan Ram Raja22-Sep-10 3:35 
GeneralRe: Better solution Pin
federico.strati22-Sep-10 5:56
memberfederico.strati22-Sep-10 5:56 
GeneralRe: Better solution - CSharp implementation Pin
federico.strati22-Sep-10 22:12
memberfederico.strati22-Sep-10 22:12 
GeneralResetting the ManualResetEvent Pin
Nikhil Contractor17-Jul-10 8:14
memberNikhil Contractor17-Jul-10 8:14 
GeneralRe: Resetting the ManualResetEvent Pin
Raghavan Ram Raja19-Jul-10 5:29
memberRaghavan Ram Raja19-Jul-10 5:29 
GeneralMy vote of 5 Pin
Nikhil Contractor17-Jul-10 7:33
memberNikhil Contractor17-Jul-10 7:33 
GeneralRe: My vote of 5 Pin
Raghavan Ram Raja19-Jul-10 5:29
memberRaghavan Ram Raja19-Jul-10 5:29 
GeneralMSDN Implementation... Pin
Paul Selormey21-Jul-08 19:10
memberPaul Selormey21-Jul-08 19:10 
GeneralRe: MSDN Implementation... Pin
Raghavan Ram Raja22-Jul-08 3:00
memberRaghavan Ram Raja22-Jul-08 3:00 
GeneralRe: MSDN Implementation... Pin
Paul Selormey22-Jul-08 11:38
memberPaul Selormey22-Jul-08 11:38 
GeneralRe: MSDN Implementation... Pin
Alon Ronen19-Sep-08 6:41
memberAlon Ronen19-Sep-08 6:41 
GeneralRe: MSDN Implementation... Pin
Paul Selormey19-Sep-08 7:34
memberPaul Selormey19-Sep-08 7:34 
GeneralRe: MSDN Implementation... Pin
Alon Ronen19-Sep-08 7:37
memberAlon Ronen19-Sep-08 7:37 
GeneralVery elegant Pin
mgvinod15-Jul-08 4:49
membermgvinod15-Jul-08 4:49 
Generalexcellent solution! Pin
Member 35280811-Jul-08 9:41
memberMember 35280811-Jul-08 9:41 
GeneralRe: excellent solution! Pin
Raghavan Ram Raja11-Jul-08 10:13
memberRaghavan Ram Raja11-Jul-08 10:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.180417.1 | Last Updated 11 Jul 2008
Article Copyright 2008 by Rammohan Raja
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid