Implement a blocking Producer/Consumer model
masterUse BlockingConcurrentQueue<T> when consumers should wait for items to become available. Note that you must coordinate the shutdown (e.g., by tracking the number of promised elements) to prevent consumers from calling wait_dequeue and blocking forever after all producers have finished.
BlockingConcurrentQueue<Item> q;
const int ProducerCount = 8;
const int ConsumerCount = 8;
// Track how many items are expected in total
std::atomic<int> promisedElementsRemaining(ProducerCount * 1000);
// Producers
for (int i = 0; i != ProducerCount; ++i) {
producers[i] = std::thread([&]() {
for (int j = 0; j != 1000; ++j) {
q.enqueue(produceItem());
}
});
}
// Consumers
for (int i = 0; i != ConsumerCount; ++i) {
consumers[i] = std::thread([&]() {
Item item;
while (promisedElementsRemaining.fetch_sub(1, std::memory_order_relaxed) > 0) {
q.wait_dequeue(item);
consumeItem(item);
}
});
}