Listing 1: A program to test queue behavior with producer/consumer threads

#include <windows.h>
#include <process.h>
#include <assert.h>
#include <deque>
#include <iostream>

// this main is the same for all iterations of the design
#if defined(BUILD_Q1)
#include "win32q1.h"
#elif defined(BUILD_Q2)
#include "win32q2.h"
#elif defined(BUILD_Q3)
#include "win32q3.h"
#endif

using namespace std;

// shared instance
BoundedInterthreadQueue ds(10);

// works with any number (>0) of producers and consumers
const int NUMBER_OF_PRODUCERS = 1;
const int NUMBER_OF_CONSUMERS = 1;
// #define SLOW_PRODUCER
#define SLOW_CONSUMER

// produce data
void producer(void *arg)
{
    Data *p;
    int   i = 0;

    // run 20 times and then quit
    for(i=0;i<20;i++) {
#ifdef SLOW_PRODUCER
        // simulate the producer being slower than the consumer
        Sleep(100);
#endif

        // allocate a new data item and send it to the queue
        p = new Data(i);
        if (p != 0) {
            cout << "put : " << GetCurrentThreadId() << " : " 
                 << i << endl;
            ds.put(p);
        }
    }

    // all done
    cout << "producer done" << endl;

    // suspend forever
    SuspendThread(GetCurrentThread());
}

// consume data
void consumer(void *arg)
{
    Data *p;
    int   i;

    // run until signaled to quit
    for(;;) {
#ifdef SLOW_CONSUMER
        // simulate the consumer being slower than the producer
        Sleep(100);
#endif
        // get next element, don't need to poll now
        p = ds.get();
        if (p != 0) {
            // get its value and delete it
            i = p->x;
            delete p;
            cout << "get : " << GetCurrentThreadId() << " : " 
                 << i << endl;
        }
    }
    // all done
    cout << "consumer done" << endl;

    // suspend forever
    SuspendThread(GetCurrentThread());
}

int main(int argc, char* argv[])
{
    unsigned long p[NUMBER_OF_PRODUCERS];
    unsigned long c[NUMBER_OF_CONSUMERS];
    int i;

    // start the worker threads
    for(i=0;i< NUMBER_OF_PRODUCERS;i++) {
        p[i] = _beginthread(producer,0,0);
    }
    for(i=0;i< NUMBER_OF_CONSUMERS;i++) {
        c[i] = _beginthread(consumer,0,0);
    }

    // suspend forever (exit the program with CTRL-C)
    SuspendThread(GetCurrentThread());

    return 0;
}