首页 > 解决方案 > 失去唤醒:如果生产者先获取互斥锁怎么办?

问题描述

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

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)

我的问题是:如果消费者先获取互斥锁,那很好---生产者将无法获取互斥锁,直到消费者在等待()释放互斥锁,因此生产者将无法在消费者实际等待之前通知()。但是如果生产者在消费者之前获得互斥锁怎么办?然后它可以在消费者等待之前通知()。据我了解,以下代码并未解决此问题。有人可以验证吗?如果事实并非如此,那么可以做些什么来绝对保证没有丢失唤醒问题?

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

标签: c++multithreadingsynchronization

解决方案


但是如果生产者在消费者之前获得互斥锁怎么办?然后它可以在消费者等待之前通知()。

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

while(not consumerReady) cv.wait(ul)

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


推荐阅读