David Sackstein
David Sackstein

Reputation: 560

Waiting for all Consumers to be in the waiting state in a Producer and Multi-Consumer implementation

Background

I have implemented a piece of code in C# which is the equivalent of a producer with many consumers using the Monitor's Wait and PulseAll methods.

I would like to provide the option for the producer to wait before producing until all consumers are waiting.

This is the simplified implementation of the consumer side:

lock (_lock)
{
    while (! _condition)
    {
        Monitor.Wait(_lock);
    }
}

And this is the simplified implementation on the producer side:

lock (_lock)
{
    _condition = true;
    Monitor.PulseAll(_lock);
}

This is a well known pattern which is fairly efficient and works well in my case.

The Problem

In some cases I would like to be able to have the producer wait before calling the producer code above until all consumers are inside the Monitor.Wait() call.

Solution Concept for Single Consumer

Let us simplify the question for the case of a single consumer. The solution requires that the producer wait on an additional synchronization object that the consumer can signal atomically with its entrance to Monitor.Wait().

Solution Concept for Multiple Consumers

Generalizing the above solution, all consumers need to access a thread safe counter which is initialized with the number of consumers.

Each consumer will atomically call Monitor.Wait() and decrement the counter. Also within the atomic call each consumer will check whether the counter is zero after the decrement and if so reinitialize the counter and signal the producer.

Summary

in a Producer and Multi-Consumer implementation in C# I need to allow the producer to wait for all Consumers to be in the waiting state before producing.

I have not found a way to implement this based on Monitors.

I would prefer a solution based on Monitors but if an entirely different approach would make this simpler, that would also be great.

Upvotes: 2

Views: 117

Answers (1)

Stephen Jennings
Stephen Jennings

Reputation: 13234

You can use a CountdownEvent for this, the consumers should signal the event, then the producer can wait to enter the lock until the countdown reaches zero.

Upvotes: 1

Related Questions