On void std::condition_variable::wait(std::unique_lock<std::mutex>& lock);
from
thread.condition
/8.3:
The function will unblock when signaled by a call to notify_one()
or a call to notify_all()
, or spuriously.
So calling notify_one()
or notify_all()
is not a prerequisite. It can unblock without any of those being called.
The above quote is from "C++20 first post-publication draft" but has remained the same since it was first written for C++11.
why there's another notify_all
, what is its purpose, or what situation is notify_all
suitable for?
When you want all waiting threads to unblock. A practical situation would be when it's time to shutdown. If you have threads blocked in a wait
they will never finish and join()
ing them will hang.
Example with a predicate saying that it should wait until either aborted
is true
or queue.empty()
is false
:
bool pop_from_queue(T& item) {
std::unique_lock<std::mutex> lock(mtx);
while(queue.empty() && not aborted) cv.wait(lock);
if(aborted) return false; // time to shutdown
// else pick an item from the queue
item = std::move(queue.front());
queue.pop();
return true;
}
When it's time to shutdown, another thread would here typically do:
aborted = true; // std::atomic<bool>
cv.notify_all();
when I call nitify_all, it will wakeup all waiting threads, then only one thread actually unblock and others remains blocking, is it called spurious wakeup?
No. A spurious wakeup is a wakeup that can happen at any time. If you call notify_all
, the waiting threads will all wakeup as ordered - not spuriously.
And if notify_one would call spurious wakeup as well?
It may cause a spurious wakeup, but that would be an implementation detail. The best thing is to just live with the fact that the threads may wakeup at any time and just check the predicate when they do.
could I precislly control where to unblock in the waiting thread(who called condition_variable.wait
with no Predicate)?
Without checking the predicate, the only thing the thread knows for sure is that it woke up. It does not now if it's for the right reason or not.