0

I have a question related to std::condition_variable. I read a lot about it and all examples shown locked mutex before using std::condition_variable like that:

std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock);
//...

or like that:

std::unique_lock<std::mutex> lock(mutex);
condition_variable.notify_one();
//...

Is it necessery to lock mutex before using condition variable or is it thread-safe?

3
  • wait requires as an argument an std::unique_lock instance that represents a locked mutex. notify_one doesn't have to be called under a mutex Commented Jul 30, 2018 at 18:22
  • What about std::unique_lock<std::mutex>(mutex, std::defer_lock) then? Commented Jul 30, 2018 at 18:29
  • Which part of "represents a locked mutex" do you find unclear? Commented Jul 30, 2018 at 20:06

1 Answer 1

1

As mentioned in the comments, notify_one() doesn't need a locked mutex in order to be called, but wait(lock) does. condition_variable is somewhat unfortunately named because it gives the option to wait unconditionally for something to happen. A more useful version is wait(lock, condition), where the thread waits only if the condition is not true, otherwise it doesn't wait at all.

An analogy can be made with a hotel reception desk, where the condition_variable in a worker thread is a receptionist, the mutex represents a critical shared resource (say, a computer for making reservations), and the condition is the presence of patrons. Checking into a hotel involves a lot of steps, most of which can be done in parallel by different receptionists, but that one step of entering your details into the computer can't - receptionists have to use the computer one at a time.

Assume that the first thing that receptionists do when they get to work is check if the computer is free (no other receptionists are using it). In the case of wait(lock), receptionists will do that and then immediately fall asleep regardless of whether there are people waiting at the reception to be checked in. In the case of wait(lock, condition) they will fall asleep only if the condition is not true (there are no people waiting).

Now, if a receptionist is asleep, they are not going to notice when there are people at the desk waiting to be checked in. That's what notify_one() does - wakes up a receptionist. The action of waking up a receptionist does not depend on the state of the computer (the mutex) - you can keep ringing the bell at the reception desk even if all the receptionists are awake and checking people in like crazy (think a 4-year-old left without supervision who finds the bell...). notify_one() wakes up one receptionist, whereas notify_all() wakes up all of them.

The analogy is not perfect, but it illustrates the dependence between a condition_variable and a locked mutex.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.