丢失唤醒:如果生产者先获取互斥量怎么办?

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

我正在尝试了解使用条件变量时丢失唤醒的问题。我相信我在下面使用了正确的设计模式。消费者:

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

制作人:

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

我的问题是:如果消费者先获取互斥锁,那没问题——直到消费者在 wait() 释放互斥锁,生产者才能获取互斥锁,因此生产者在消费者实际等待之前将无法通知()。 但是如果生产者在消费者之前获得互斥量怎么办?那么它可以在消费者等待之前通知()。据我了解,下面的代码没有解决这个问题。有人可以验证这一点吗?如果确实没有,如何才能绝对保证不存在丢失唤醒的问题?

#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;
}

But what if the producer acquires the mutex before the consumer? Then it could notify() before the consumer is waiting.

没问题。 您的 cv.wait(ul, [this]{ return consumerReady; });

相同
while(not consumerReady) cv.wait(ul)

因此,首先检查实际的 consumerReady 变量,只有在未设置时才会进入等待模式。

您遗漏了制作人的关键步骤:

 lock the mutex
_make the condition TRUE_
 signal the condition variable

如果 prodcer 在前,那么你是对的:信号会丢失。但这并没有什么坏处,因为消费者会看到条件已经为真,因此它不会等待信号。