Are std::condition_variable wait predicates thread-safe?
Asked Answered
L

1

5

Take this code:

std::condition_variable var;
var.wait(lock, [&sharedBool] { return sharedBool; });

When var reads from sharedBool, is that thread safe? If it isn't, is making sharedBool a std::atomic<bool> reasonable?

Leslee answered 30/5, 2023 at 18:56 Comment(1)
You should use { std::unique_lock<std::mutex> lock{your_mutex}; sharedBool = newvalue; var.notify_all(); } (or notify_one) to update your bool and trigger an evaluation of the predicate. An extra synchronization primitive will only complicate things.Guerin
C
6

Reading from sharedBool happens under the protection of the mutex locked by lock.

As long as all concurrent accessed to sharedBool happen while a lock to the same mutex is held, your program is thread-safe.

Since you also cannot wait on a condition variable without holding a lock, it is usually not reasonable to use an atomic for this use case.

Cover answered 30/5, 2023 at 19:0 Comment(7)
Doesn't wait unlock the unique_lock, and only lock it when wait exits?Leslee
@Leslee Yes, but it re-locks before invoking the predicate. Everything inside the lambda body is only executed while the lock is held.Cover
I see, thanks. How did you know about it locking before checking the predicate, as I can't find anything on cppreference about that.Leslee
@Leslee Do you understand what an atomic "unlock and wait" operation is and how that's the whole point of a condition variable?Runt
@Leslee Look here: Note that lock must be acquired before entering this method, and it is reacquired after wait(lock) exits, which means that lock can be used to guard access to stop_waiting().Cover
@Leslee You're very welcome. These things can be subtle, so it's better to ask than make assumptions and get it wrong.Cover
@Leslee I ought to note that using atomics inside the condition variable's wait frequently leads to misuse and invalidating requirements of the condition variable, leading to problems like occasional infinite waits.Maidy

© 2022 - 2024 — McMap. All rights reserved.