Lost wake-up: What if the producer acquires the mutex first?

  c++, multithreading, synchronization

I’m trying to understand the lost wake-up issue when using condition variables. I believe I have used the proper design-pattern below. The consumer:

lock the mutex
while the condition is not satisfied
    wait on the condition variable
consume
unlock the mutex

and the producer:

lock the mutex
produce
unlock the mutex
signal the condition variable (notify consumer)

My problem is this: If the consumer acquires the mutex first, it is fine—the producer won’t be able to acquire the mutex until the consumer releases the mutex at wait(), and so the producer won’t be able to notify() before the consumer is actually waiting. But what if the producer acquires the mutex before the consumer? Then it could notify() before the consumer is waiting. To my understanding the code below does not address this issue. Can someone verify this? If in fact it does not, what could be done to absolutely guarantee that there is no lost wake-up issue?

#include <iostream>
#include <thread>
#include <mutex>
#include <thread>
#include <condition_variable>

using namespace std;    

class Foo {
        mutex m;
        condition_variable cv;
        bool consumerReady;

    public:
    Foo() {
        consumerReady = false;
    }

    void producer() {
        {
            unique_lock<mutex> ul(m);
            cout << "produced"<<endl;
            consumerReady = true;
        }
        cv.notify_one();
    }

    void consumer() {
        unique_lock<mutex> ul(m);
        cv.wait(ul, [this]{ return consumerReady; });
        cout<<"consumed"<<endl;
        consumerReady = false;
    }
};

int main() {
    Foo* z = new Foo();

    thread t1(&Foo::producer, z);
    thread t2(&Foo::consumer, z);

    t1.join();
    t2.join();

    return 0;
}

Source: Windows Questions C++

LEAVE A COMMENT