educative.io

Question on condVar.wait

It says here:
The call to wait locks the mutex and checks if the predicate []{ return dataReady; } evaluates to true.

  • If true, the condition variable unlocks the mutex and continues.
  • If false, the condition variable unlocks the mutex and puts itself back in the wait state.
    If dataReady is true should not the condition variable lock the mutex and unlock it after parenthesis{} of unique_lock?

Course: https://www.educative.io/courses/concurrency-with-modern-cpp
Lesson: https://www.educative.io/courses/concurrency-with-modern-cpp/RLQgmxY6ERz

Hi @Aditya_Sharma !!
The statement you’re referring to is explaining the behavior of the std::condition_variable::wait method. Let’s break it down and clarify the sequence of actions:

  1. When a thread calls condVar.wait(lck, []{ return dataReady; }), it first locks the mutex mutex_ that is associated with the condition variable condVar. This prevents other threads from modifying shared data while this thread is waiting.
  2. Once the mutex is locked, the condition variable evaluates the provided predicate []{ return dataReady; }. This predicate is a callable object that returns a boolean value.
  3. If the predicate evaluates to true (meaning dataReady is true), then the condition variable unlocks the mutex and allows the thread to continue execution. In this case, the thread proceeds to execute the work (in the example, the doTheWork() function).
  4. If the predicate evaluates to false (meaning dataReady is false), then the condition variable unlocks the mutex and puts the calling thread to sleep (waits). The mutex remains locked during this time to ensure that other threads cannot modify shared data.
  5. When the condition variable receives a notification (e.g., condVar.notify_one() or condVar.notify_all()), it wakes up the waiting thread(s). The awakened thread(s) will then reacquire the lock on the mutex before continuing execution. This is necessary to ensure proper synchronization and avoid data races.
  6. After being awakened and reacquiring the lock, the thread will reevaluate the predicate. If the predicate now evaluates to true (because dataReady might have been modified by another thread), the thread will proceed as described in step 3. If the predicate still evaluates to false, the thread may go back to sleep until another notification is received.

Regarding your question:

If dataReady is true should not the condition variable lock the mutex and unlock it after parenthesis{} of unique_lock?

The unlocking of the mutex happens inside the wait method itself, not after the lambda expression {}. The purpose of unlocking the mutex is to allow other threads to modify shared data while the calling thread is waiting. The unlocking and locking of the mutex are handled internally by the wait method to ensure proper synchronization.
I hope it helps. Happy Learning :blush: