What's the difference between notify_all() and notify_one() of std::condition_variable?
Asked Answered
S

1

62

Currently, I am implementing a multi-thread project using std::thread in C++11. I use std::condition_variable to synchronize threads. In detail, one consumer function calls wait() member function of std::condition_variable to wait for task from a global task queue, another producer function generates and puts tasks into the queue. But I do not know the difference between notify_all() and notify_one() member functions of std::condition_variable. Which function should I use in the producer function? Thanks!

Selfsupporting answered 26/1, 2012 at 8:58 Comment(0)
R
63

If there are ten threads blocked on the condition variable, for example, notify_one() will unblock only one thread, while notify_all() will unblock them all. In your case, you'll want to use notify_one() so you don't wake up threads that don't have any work waiting for them.

Rent answered 26/1, 2012 at 9:0 Comment(6)
Thanks, GMan. I read some documents from the internet. Just as what you said. However, typically the wait() function is used on a mutex, e.g. std::unique_lock<std::mutex> ul(m_mutexTask); while (m_lTask.empty()) { m_condTask.wait(ul); } . Then even notify_all() wake up all threads, there is only one thread could lock the mutex, right?Selfsupporting
Only one thread will lock the mutex at a time, but they'll all return from the wait as soon as they get the mutex.Modred
@Yun: Which one to use depends really on whether any of the waiting threads can handle the thing that's being waited for. If any would do (e.g., multiple identical readers on a queue) then you use notify_one as that's definitely more efficient. If there's a more complex condition such that only one waiting thread could actually succeed with the loop condition, you've got to wake up all of them as you can't control which thread will be woken by notify_one.Coleorhiza
And if there's only one waiting thread, then it makes no difference which you use. So you might as well use notify_all in case you ever add more waiters in future -- since waiters on a condition variable can wake up for no reason, and must be written to deal with that correctly, adding extra wakes does no harm other than perhaps to performance. Whereas if you use notify_one, you might accidentally write code that relies on the "right" thread being chosen. It might appear to work and pass all your tests, but then some subtle change in future causes it to stop working.Inquisitorial
How much more efficient is notify_one() so that we need to take care on using notify_all when we only have one thread waiting at the moment?Blather
@Blather You can measure it, and it probably varies between different platforms. One result I have found is here: github.com/Haivision/srt/pull/2287Auten

© 2022 - 2024 — McMap. All rights reserved.