Concurrency
C++ Condition Variables
Condition Variables
C++ condition variables use std::condition_variable for synchronization.
Introduction to Condition Variables
Condition variables in C++ are synchronization primitives that enable threads to wait until a particular condition is met. They work with std::mutex
to manage the synchronization of shared resources. The std::condition_variable
class is part of the C++ standard library and is essential in multi-threaded programming.
Basic Usage of std::condition_variable
The primary operations for a condition variable are wait
, notify_one
, and notify_all
. The wait
operation blocks the current thread until the condition variable is notified. The notify_one
operation wakes up one waiting thread, and notify_all
wakes up all waiting threads.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id(int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// Proceed once 'ready' is true
std::cout << "Thread " << id << std::endl;
}
void set_ready() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
int main() {
std::thread threads[10];
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(print_id, i);
std::this_thread::sleep_for(std::chrono::seconds(1));
set_ready();
for (auto& th : threads) th.join();
return 0;
}
Understanding the Wait Function
The wait
function is crucial for condition variables. It releases the mutex while the thread is waiting and automatically re-acquires it once the thread is notified and the wait condition is satisfied. This is typically used in a loop to check the condition repeatedly.
Using notify_one and notify_all
The notify_one
function wakes up a single waiting thread, which can be useful when only one thread should proceed. In contrast, notify_all
resumes all waiting threads, which is useful when multiple threads need to proceed after a condition is met. Choosing between these depends on the specific needs of your application.
Best Practices and Considerations
- Always use a
std::unique_lock
with a condition variable. This is necessary for thewait
function to work properly. - Be cautious of spurious wakeups, which are false wakeups that can occur. Always use a loop to check the condition.
- Avoid using
notify_all
if only one thread needs to be notified, as it can lead to inefficiencies. - Ensure the condition variable and the corresponding mutex are accessible to all threads that need to use them.
- Previous
- Async
- Next
- File Reading