Why is there a Ready and Waiting queue for every object when using a monitor? If a thread is done with an object, just pop the next item in the Waiting queue. The Ready queue seems redundant.
The context is .NET, more specifically the monitor class.
A producer/consumer queue is a really good use case for learning about the Monitor class.
Assume that work is sporadically added to the queue. Sometimes there are a lot of items needing to be processed, sometimes long periods of time will elapse with no items in the queue.
So, let's say you have k consumer threads waiting around to process items in the queue. In other words, each thread implements a tight loop, constantly trying to
lock on the queue (this puts you in the Monitor's "ready" queue).If you choose option "a", your k threads will be wasting CPU cycles moving through the ready queue over and over, finding no work to do, and starting all over again at the back of the queue.
If you choose option "b", you're saying "there's nothing here to do right now, let me sleep, and wake me up when there's something to do".
With option "b", if the queue is empty, you will soon find all of your consumers sleeping in the "waiting" queue, and no CPU time being wasted.
Then, when a producer adds an item to the queue, it calls Monitor.Pulse. This wakes up the first thread in the "waiting" queue, which then goes to the back of the "ready" queue (which is also the front of the queue if the "ready" queue was empty).
When a thread gets the lock and consumes this item from the queue, it calls Monitor.Enter again, and goes to the back of the "ready" queue.
See this article for a classic implementation of a producer/consumer queue in .NET.
Assuming I've understood your question properly, the two serve different purposes.
The "ready" queue is for threads which are ready to run as soon as they can obtain the lock. They're just waiting to acquire the lock. This is mostly used for mutual exclusion, to prevent two threads from both using the same resource at the same time.
The "waiting" queue is for threads which are waiting for a particular signal - namely the monitor being pulsed. This is often used for co-ordination - for example in a producer/consumer queue, where if the queue is empty, a consumer will wait until a monitor is pulsed before it checks the queue again. While no-one is producing and no-one is consuming, no thread owns the monitor - there's no resource in use. But the monitor is used to co-ordinate the consumer with the producer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With