I am using a multi-threaded producer/consumer queue with a single (very fast) producer and many, much slower, consumers. Each consumer has exclusive access to a piece of physical hardware, such as a phone line. The producer runs on the main thread and each consumer runs on its own thread. Each consumer thread is created and initialized when the program starts up.
What I am attempting to do is always use the first consumer if available, if it is busy then use the second consumer. If the first two are busy then use the third and so on. If consumer two is busy and consumer one is now ready, then it should use the first.
Simply locking the queue and using monitor.pulse when an item is en-queued in the producer and monitor.wait in the consumer (with the wait condition being the queue is empty) does not work since each consumer enters the wait queue at the mercy of the thread scheduler. This results in each consumer being used in a round-robin fashion.
Is there an easy way to pull this off?
EDIT:
Just implemented this by creating a list of hardware-bound objects that the consumer threads lock, waiting if there are none available, then passing the work item to the acquired device. Once the consumer is finished with the device, it sets it as available and pulses a waiting thread (if any).