8

Thanks to the book of the Doctor Scott Meyers, page 263, I recently discovered condition_variable, so I had to search about it on cppreference to study it more.

https://en.cppreference.com/w/cpp/thread/condition_variable

I have several questions on it, because I think on it since several days, and I still did not understand.

My questions are about this piece of code :

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();

1) I do not understand what the author of the cppreference means by that comment and by "the waiting thread, only to block again" because I don't know even how to translate it, and

2) Which threads it denotes exactly, and why in particular.

3) Does it denote the thread_worker or the main thread (parent) ?

4) What they chose to do that ?

And what does it change if the authors notify first and then manually unlock ?

Dev
  • 463
  • 3
  • 12

1 Answers1

6

That's a minor and usually irrelevant optimization. The concern arises because each thread that wakes up after a call to notify or notify_all has to lock the mutex before it is allowed to proceed. If the call to unlock occurs after the call to notify_one (or to notify), the thread(s) that wake up will have to wait until after the calling thread unlocks it. If the call to unlock is made before the notify call then one awakened thread can get the mutex immediately.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • I posted a new comment and I have completed my first post – Dev Jul 11 '19 at 19:23
  • Thank you Pete Becker. Could you explain to me pricesely, what does it mean, when the author of cppreference writes : Manual unlocking is done before notifying, to avoid waking up // the waiting thread only to block again (see notify_one for details) in the example https://en.cppreference.com/w/cpp/thread/condition_variable What does it mean "the waiting thread only to block again" Because i try to understand it in french. Which thread does it denote in the example of cppreference ? Is it the main thread or the thread_worker ? Thank you for your help – Dev Jul 11 '19 at 19:27
  • 2
    The main thread blocks on the condition variable, waiting for the worker thread to finish. When the worker thread is finished it calls `notify_one` to wake up the main thread. The concern is that the main thread might be inconvenienced if the mutex isn't immediately available. – Pete Becker Jul 11 '19 at 19:33
  • Finally, I think I understood, please correct me dear Pete if I am not right : 1) the mutex cannot be shared between 2 threads at the same time 2) in the sentence, "the waiting thread only to block again" denotes the main thread. 3) so if the notify is before the "unlock", there is a first spurious wake up of the main thread before the std::mutex is not yet got again by the main thread. But after the unlock, there is a second wake up , which is the good one as and the main thread resumes as the mutex is acquired by the main thread at that moment. What do you think ? – Dev Jul 11 '19 at 21:33
  • 2
    A spurious wake up is something entirely different. A condition variable is allowed to release a thread without a call to `notify..l`. That’s a spurious wake up, and it’s why code typically runs a loop: `while (!condition) condition_variable.wait();`. – Pete Becker Jul 11 '19 at 23:12
  • 2
    When a thread gets released by a condition variable there are two steps: waking up the thread, and locking the mutex. If the mutex is locked for any reason the thread will block until the thread that holds lock releases it. – Pete Becker Jul 11 '19 at 23:17