On my neverending quest to understand std::contion_variable
s I've run into the following. On this page it says the following:
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// ...
std::cout << "thread " << id << '\n';
}
And after that it says this:
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
Now as I understand it, both of these functions will halt on the std::unqique_lock
line. Until a unique lock is acquired. That is, no other thread has a lock.
So say the print_id
function is executed first. The unique lock will be aquired and the function will halt on the wait line.
If the go
function is then executed (on a separate thread), the code there will halt on the unique lock line. Since the mutex is locked by the print_id
function already.
Obviously this wouldn't work if the code was like that. But I really don't see what I'm not getting here. So please enlighten me.
It's just the way that condition variables are (or were originally) implemented. The mutex is used to protect the condition variable itself. That's why you need it locked before you do a wait. The wait will "atomically" unlock the mutex, allowing others access to the condition variable (for signalling).
std::condition_variable::wait 1) Atomically unlocks lock , blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously.
look up how a unique_lock() behaves. @Prab, just to give the explanation: unique_lock() is automatically released when the destructor is called meaning it is exception safe and that it automatically unlocks when you leave scope.
std::condition_variable The condition_variable class is a synchronization primitive used with a std::mutex to block one or more threads until another thread both modifies a shared variable (the condition) and notifies the condition_variable .
What you're missing is that wait
unlocks the mutex and then waits for the signal on cv
.
It locks the mutex again before returning.
You could have found this out by clicking on wait on the page where you found the example:
At the moment of blocking the thread, the function automatically calls lck.unlock(), allowing other locked threads to continue.
Once notified (explicitly, by some other thread), the function unblocks and calls lck.lock(), leaving lck in the same state as when the function was called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With