std::condition_variable
(C++)
Saw this while working on my SLAM for VR Headset project.
The condition_variable
is used to wake up threads that are waiting on data.
Resources
- https://www.geeksforgeeks.org/thread-synchronization-in-cpp/
- https://www.geeksforgeeks.org/cpp-multithreading-condition-variables/
- https://en.cppreference.com/w/cpp/thread/condition_variable/wait
Include
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.
What happens when cv.wait()
is called:
cv.wait
releases the lock and BLOCKS on*this
(source)- After being woken up (through
cv.notify_one()
orcv.notify_all()
on another thread,cv.wait()
checks the condition of second argument (a lambda function returning true or false).- If the predicate returns
true
, the waiting ends, and the thread proceeds with the next steps. Mutex is LOCKED again. - If the predicate returns
false
, the thread goes back to waiting and blocks. Mutex is UNLOCKED.
- If the predicate returns
Why is the mutex needed, isn't the condition variable enough?
No, you need them in conjunction. Imagine a scenario where you have multiple consumers to the same producer. A condition variable is used to make sure that we only consume from the queue when it is non-empty. However, without a
mutex
, after condition variable unblocks, since you’re not using a mutex, the rest of the code doesn’t guarantee that the queue is not empty. You can have a Race Condition again.
The second argument explained:
Another example
notify_one
vs. notify_all
https://stackoverflow.com/questions/43759609/stdcondition-variablenotify-all-i-need-an-example