Welcome back to CodeYourCraft! Today, we're diving into one of the most powerful synchronization tools in C++ ā the std::condition_variable. This versatile beast helps manage concurrent execution, signaling threads, and handling complex multi-threaded scenarios. Let's explore it together! šÆ
std::condition_variable is a C++11 library that facilitates communication between threads. It allows one or more threads to wait for a particular condition to become true, and it notifies other threads when that condition is met. š
Imagine having a busy kitchen where multiple cooks are preparing different dishes simultaneously. One cook can't start preparing a certain dish until another finishes preparing its required ingredients. std::condition_variable helps these cooks (threads) communicate effectively and synchronize their work. š”
std::condition_variable relies on a std::unique_lock to protect shared data from race conditions.Let's create a simple producer-consumer problem using std::condition_variable. Here, a producer generates numbers, and a consumer consumes them.
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
std::queue<int> numbers;
std::mutex mtx;
std::condition_variable cvProducer, cvConsumer;
void producer() {
int count = 0;
for (int i = 0; i < 10; ++i) {
std::unique_lock<std::mutex> lock(mtx);
cvProducer.wait(lock, []{ return numbers.size() < 5; }); // wait until queue size < 5
numbers.push(count);
std::cout << "Produced: " << count++ << "\n";
lock.unlock();
cvConsumer.notify_one();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cvConsumer.wait(lock, []{ return !numbers.empty(); }); // wait until queue is not empty
int number = numbers.front();
numbers.pop();
std::cout << "Consumed: " << number << "\n";
lock.unlock();
cvProducer.notify_one();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main() {
std::thread producerThread(producer);
std::thread consumerThread(consumer);
producerThread.join();
consumerThread.join();
return 0;
}What is the purpose of the `std::unique_lock` in the example?
That's it for today! In the next lesson, we'll delve deeper into std::condition_variable and explore more advanced usage scenarios. Stay tuned and happy coding! š”šÆ