Do I need to lock the mutex before calling condition_variable::notify()?

Viewed 92

I'm reading some example code of condition_variable:

At cppreference, the notify_one() is called like this: https://en.cppreference.com/w/cpp/thread/condition_variable

{
    std::lock_guard lk(m);
    ready = true;
    std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();

from the code above, it's clear that it's not necessary to use any mutex to call notify_one().

But at cplusplus.com, the code is like this: https://cplusplus.com/reference/condition_variable/condition_variable/

std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();

It seems that a mutex should be used before calling notify_all().

I'm confused, is a mutex necessary for notify_*() function?

1 Answers

It is not mandatory to call notify_one or notify_all under the lock holding the mutex.

From the std::condition_variable documentation:
The 3rd thing the thread that intends to modify the shared variable has to do is:

execute notify_one or notify_all on the std::condition_variable (the lock does not need to be held for notification)

(emphasis is mine).

However - it might offer some performance benefit to call notify_* under the lock.

From the comment to my answer here (credit goes to @DavidSchwartz):

You gratuitously make the notify_all more expensive by unlocking the mutex before calling it. If you call notify_all while holding the mutex, most modern implementations know that it cannot make any thread ready-to-run (because they need to acquire the mutex to make forward progress) and can make wait morphing optimizations. The way this is coded, both notify_all and the destructor of lck can make a thread ready-to-run, resulting in reduced performance.

Related