是否有notify_one()队列?

问题描述 投票:1回答:1

考虑第一线程函数和全局变量:

    std::mutex mut;
    std::condition_variable officer;
    bool firstPlayerIsReady = false;
    bool secondPlayerIsReady = false;

void firstPlayer(){
    constexpr auto doIt = true;
    while(doIt)
    {
        std::unique_lock lock{mut};
        auto toContinue = ring();
        secondPlayerIsReady = true;
        firstPlayerIsReady = false;
        officer.notify_one();   //#1
        if(!toContinue) return;
        officer.wait(lock,[=](){ return firstPlayerIsReady;});
    }
}

它调用一些环和环()返回一个继续条件;然后,它更新准备值下一个循环的每个线程;

考虑下一个线程:

void secondPlayer(){
    constexpr auto doIt = true;
    while(doIt)
    {
        auto period = std::chrono::seconds(5);
        std::this_thread::sleep_for(period);

        std::unique_lock lock{mut};   //#2
        officer.wait(lock,[this](){ return secondPlayerIsReady;});
        auto toContinue = ring();
        firstPlayerIsReady = true;
        secondPlayerIsReady = false;
        officer.notify_one();
        if(!toContinue) return;
    }
}

这个线程等待5秒,然后等待(),直到第一个线程被锁定后调用notify_one();此外,类似于第一个线程。

先验,与#1标签线路被先前执行比用#2标签的线,因此,通知已早先发送比所述第二线程被锁定。现在的问题是 - 是否有notify_one()队列?否则,该通知未发送,效果显着。

c++ multithreading race-condition
1个回答
5
投票

没有队列。如果一个线程调用notify_one并且没有其他线程等待它不会做任何事情。

这就是为什么你有谓语,在你的榜样

officer.wait(lock,[this](){ return secondPlayerIsReady;});

一个线程调用此所以的时候,如果secondPlayerIsReady是真实的,那么该线程将不会等待,只是跳过这一行。

因此调用notify_one过“早”是没有问题的,只要标志设置正确。只要记住该标志需要修改时,必须由互斥保护。

© www.soinside.com 2019 - 2024. All rights reserved.