4

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?

TwistedBlizzard
  • 931
  • 2
  • 9
  • You should use `{ std::unique_lock 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. – Pepijn Kramer May 30 '23 at 18:59

1 Answers1

5

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.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
  • Doesn't wait unlock the unique_lock, and only lock it when wait exits? – TwistedBlizzard May 30 '23 at 19:02
  • @TwistedBlizzard Yes, but it re-locks before invoking the predicate. Everything inside the lambda body is only executed while the lock is held. – ComicSansMS May 30 '23 at 19:03
  • I see, thanks. How did you know about it locking before checking the predicate, as I can't find anything on cppreference about that. – TwistedBlizzard May 30 '23 at 19:09
  • @TwistedBlizzard Do you understand what an atomic "unlock and wait" operation is and how that's the whole point of a condition variable? – David Schwartz May 30 '23 at 19:11
  • 1
    @TwistedBlizzard Look [here](https://en.cppreference.com/w/cpp/thread/condition_variable/wait): *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()`.* – ComicSansMS May 30 '23 at 19:11
  • 1
    @TwistedBlizzard You're very welcome. These things can be subtle, so it's better to ask than make assumptions and get it wrong. – ComicSansMS May 30 '23 at 19:13
  • @TwistedBlizzard 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. – ALX23z May 30 '23 at 21:06