C ++-由不同线程通知的std :: condition_variable

时间:2018-07-04 12:52:45

标签: c++ multithreading

我正在尝试从两个不同的线程通知事件。主线程在第一个<button class="myButton">Hover this button</button>调用时唤醒,但在第二个调用时不唤醒。这是使用条件变量的正确方法吗?

buttonfullwidth
buttonfullwidth:hover

buttonfullwidth_1
buttonfullwidth_1:hover

buttonfullwidth_2
buttonfullwidth_2:hover

buttonfullwidth_3
buttonfullwidth_3:hover

buttonfullwidth_4
buttonfullwidth_4:hover

1 个答案:

答案 0 :(得分:1)

尝试此代码。请注意,条件变量接受一个谓词,该谓词首先检查是否满足条件,然后进行锁定。当您通知变量时,它将运行谓词(不带锁),如果条件为true,则线程将拥有该锁,否则调用线程将继续等待下一个通知。

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

auto is_ready_1=false;
auto is_ready_2=false;
std::mutex m;
std::condition_variable cv;

void test1()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::unique_lock<std::mutex> lk(m);
    is_ready_1 = true;
    cv.notify_one();
}
void test2()
{
    std::this_thread::sleep_for(std::chrono::seconds(6));
    std::unique_lock<std::mutex> lk(m);
    is_ready_2 = true;
    cv.notify_one();
}

int main()
{
    std::thread t1(test1);
    std::thread t2(test2);

    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, [] {
        if (!is_ready_1)
        {
            std::cout << "Spurious 1" << std::endl;
        }
        return is_ready_1;
    });
    //preceding line must clear before this is executed
    cv.wait(lk, [] {
        if (!is_ready_2)
        {
            std::cout << "Spurious 1" << std::endl;
        }
        return is_ready_2;
    });

    t1.join();
    t2.join();
    system("pause");
}

在Windows 10上,我还看到了两个虚假的唤醒事件,我怀疑这些事件是在线程从睡眠中唤醒时发生的。