2

I've seen a lot of implementations of the semaphore where the notify() function looks something like this: (this particular example is from here)

void notify() {
        std::lock_guard<decltype(mutex_)> lock(mutex_);
        ++count_;
        condition_.notify_one();
    }

I don't understand the reason behind holding the lock while calling notify_one(). Even if a spurious wake-up occurs after releasing the mutex but before notifying the condition variable, everything should work fine (since condition_.wait() should use a predicate to handle spurious wakeups anyway).

Are there any cases where this:

void notify() {
        {
        std::scoped_lock lock(mutex_);
        ++count_;
        }
        condition_.notify_one();
    }

would fail?

  • Some condition variables do require the lock be held for the notify for [various reasons](https://stackoverflow.com/a/46234855/8586227); it might just be habit that people do so where it’s explicitly not required. – Davis Herring May 23 '20 at 21:54
  • https://stackoverflow.com/questions/48958530/should-condition-variable-notify-all-be-covered-by-mutex-lock this is an almost identical question that I asked. It has good answers that will help with your understanding of this subject. – ttemple May 25 '20 at 23:41

1 Answers1

2

According to cppreference (emphasis mine):

The thread that intends to modify the variable has to

  1. acquire a std::mutex (typically via std::lock_guard)
  2. perform the modification while the lock is held
  3. execute notify_one or notify_all on the std::condition_variable (the lock does not need to be held for notification)

So either of the code sequences in your post should be OK.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48