std::condition_variable
(C++)
Saw this while working on my SLAM for VR Headset project.
The condition_variable
is mainly used to notify the threads about the state of the shared data. It is used with the mutex locks to create processes that automatically wait and notify the state of the resource to each other.
AHA: It’s kind of like using Semaphores?
Resources
- https://www.geeksforgeeks.org/thread-synchronization-in-cpp/
- https://www.geeksforgeeks.org/cpp-multithreading-condition-variables/
Include
#include <condition_variable>
Notify One vs. Notify All
notify_one()
wakes up only one of the waiting threads and unblock them (more efficient in scenarios where waking up a single thread is sufficient because it avoids unnecessarily waking up multiple threads)notify_all()
wakes up all threads waiting on the condition variable. This is necessary in situations where multiple threads may be waiting for the same condition and all need to recheck the condition when it changes.
Good to solve the Producer-Consumer Problem.
mutex mtx;
condition_variable cv;
bool data_ready = false;
void producer() {
// Simulate data production
this_thread::sleep_for(chrono::seconds(2));
// lock release
lock_guard<mutex> lock(mtx);
// variable to avoid spurious wakeup
data_ready = true;
// logging notification to console
cout << "Data Produced!" << endl;
// notify consumer when done
cv.notify_one();
}
void consumer() {
// locking
unique_lock<mutex> lock(mtx);
// waiting
cv.wait(lock, [] { return data_ready; });
cout << "Data consumed!" << endl;
}
// drive code
int main() {
thread consumer_thread(consumer);
thread producer_thread(producer);
consumer_thread.join();
producer_thread.join();
return 0;
}
Why is the mutex needed, isn't the condition variable enough?
No, you need them in conjunction.
Another example
// condition variable and mutex lock
condition_variable cv;
mutex m;
// shared resource
int val = 0;
void add(int num) {
lock_guard<mutex> lock(m);
val += num;
cout << "After addition: " << val << endl;
cv.notify_one();
}
void sub(int num) {
unique_lock<mutex> ulock(m);
cv.wait(ulock,
[] { return (val != 0) ? true : false; });
if (val >= num) {
val -= num;
cout << "After subtraction: " << val << endl;
}
else {
cout << "Cannot Subtract now!" << endl;
}
cout << "Total number Now: " << val << endl;
}
// driver code
int main()
{
thread t2(sub, 600);
thread t1(add, 900);
t1.join();
t2.join();
return 0;
}
notify_one
vs. notify_all
https://stackoverflow.com/questions/43759609/stdcondition-variablenotify-all-i-need-an-example