Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do both the notify and wait function of a std::condition_variable need a locked mutex

On my neverending quest to understand std::contion_variables 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.

like image 249
laurisvr Avatar asked May 13 '15 08:05

laurisvr


People also ask

Why do condition variables need a lock?

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).

Does condition variable wait release lock?

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.

Does unique_lock automatically unlock?

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.

What is std :: Condition_variable?

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 .


1 Answers

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.

like image 94
molbdnilo Avatar answered Nov 15 '22 05:11

molbdnilo