A condition variable can be used to communicate between 2 threads. It always has to be associated with a mutex.
Essentially, it:
-
unlocks the mutex while waiting for a notification
-
re-locks the mutex after being notified
// Case 1: no condition variable
// => no communication between threads my_thread and main
int main() {
auto start = std::chrono::high_resolution_clock::now();
std::thread my_thread([&]{
std::this_thread::sleep_for(std::chrono::seconds(3));
});
std::cout << "No wait." << std::endl;
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "Elapsed time: " << elapsed.count() << " ms\n";
// "No wait." arrives after few milliseconds only (no waiting)
my_thread.join();
return 0;
}
// Case 2: use of a condition variable
// => the main thread waits until a condition is reached in my_thread
int main() {
std::mutex mtx;
std::condition_variable cv;
bool done = false;
auto start = std::chrono::high_resolution_clock::now();
std::thread my_thread([&]{
std::this_thread::sleep_for(std::chrono::seconds(3));
{
std::lock_guard<std:: mutex> lock(mtx);
done = true;
}
cv.notify_one();
});
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [&]() { return done; });
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "Elapsed time: " << elapsed.count() << " ms\n";
// "Wait." arrives after 3 seconds (after being notified)
std::cout << "Wait." << std::endl;
my_thread.join();
return 0;
}