如果虚假唤醒,消费者线程是否会收到condition_variable通知信号

时间:2017-05-13 14:40:01

标签: c++ multithreading

我们知道条件变量会受到虚假唤醒的影响。假设我们有一个1-producer-1-consumer队列与互斥和条件变量同步。消费者线程得到了虚假的唤醒。 问题是 - 消费者线程是否会错过来自生产者的通知信号? 我理解它极不可能......但是仍然有可能丢失队列中的最后一个元素吗?

2 个答案:

答案 0 :(得分:2)

如果调用lock the mutex while the condition is not satisfied wait on the condition variable 的代码没有写好,那么它确实会错过唤醒。但那会有点不正常。通常的习语是:

lock the mutex
signal the condition variable

信令线程应该在发信号之前锁定互斥锁:

matplotlib

等待条件变量会在等待期间解锁互斥锁。但是,当等待调用返回时,互斥锁将被锁定。因此,在虚假唤醒时,等待线程将保持互斥锁,直到它恢复等待。当等待线程保持互斥锁时,信令线程不能发信号通知条件变量。当等待线程实际等待时,互斥锁被解锁并且信令线程可以继续并发出信号;等待线程将获取信号,一旦信令线程释放互斥锁,等待线程将继续执行。

所以,不,正确的代码不会错过信号。但是如果等待线程释放互斥锁并在检查其状态的过程中重新获取它,则信号可能在等待线程调用等待之前发生,并且信号将丢失。不要这样做。 &LT g取代;

答案 1 :(得分:1)

虚假醒来意味着它可能会虚假地醒来然后不得不继续等待。

它根本没有提到错过事件的可能性,因为如果这是真的就没用了。

此链接提供了cv和等待方法的详细说明:

https://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables

 // print a starting message
    {
        std::unique_lock<std::mutex> locker(g_lockprint);
        std::cout << "[logger]\trunning..." << std::endl;
    }

    // loop until end is signaled
    while(!g_done)
    {
        std::unique_lock<std::mutex> locker(g_lockqueue);

        g_queuecheck.wait(locker, [&](){return !g_codes.empty();});

        // if there are error codes in the queue process them
        while(!g_codes.empty())
        {
            std::unique_lock<std::mutex> locker(g_lockprint);
            std::cout << "[logger]\tprocessing error:  " << g_codes.front() << std::endl;
            g_codes.pop();
        }
    }