【问题标题】:what happen between after notify_all() and before wait() get the lock?在 notify_all() 和 wait() 获得锁之前之间会发生什么?
【发布时间】:2020-06-29 10:48:31
【问题描述】:

我使用以下代码测试std::condition_variable

class CondWait{
public:
    std::condition_variable cv;
    std::mutex mu;
    int i=0;
public:
    void mainTask(){
        std::unique_lock<std::mutex> lk(mu);
        cv.wait(lk);
        i++;
        std::cout<<"main task, "<<i<<std::endl;
    }
    void notifyTask(){

        std::unique_lock<std::mutex> lk(mu);
        i = 0;
        std::cout<<"notify task, "<<i<<std::endl;
        cv.notify_one();
        std::cout<<"notify task, sleep 5 sec"<<std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
};
int main()
{
    CondWait condwait;
    std::thread t1(&CondWait::mainTask,&condwait);
    std::thread t2(&CondWait::notifyTask,&condwait);
    t1.join();
    t2.join();

    return 0;
}

有时,输出如下,程序被阻塞:

notify task, 0
notify task, sleep 5 sec

有时,程序会运行良好,即休眠5秒后,会输出main task, 1,完整输出为:

notify task, 0
notify task, sleep 5 sec
main task, 1

在我看来,在notifyTask线程中,在notify_one之后仍然使用互斥锁,所以mainTask中的wait无法锁定互斥锁。但是不知道接下来会发生什么,为什么这个例子会有歧义的表现。你能提供一些建议吗?非常感谢!

【问题讨论】:

    标签: multithreading c++11 concurrency condition-variable


    【解决方案1】:

    由于您同时启动两个线程,可能会出现以下情况:cv.notify_one()mainTask 中的 cv.wait() 之前被调用,并且由于还没有线程在等待,因此函数 什么都不做。之后,wait() 被执行并挂起等待通知

    【讨论】:

    • 感谢您的回答,我在创建两个线程之间添加了延迟。结果验证了你的答案是正确的。我想进一步问为什么wait() 可以等到notifyTask 释放锁。我认为wait 应该在notify_all() 执行后尝试获取锁。
    • wait 在收到通知后立即尝试获取锁,但必须等到notify 线程完成释放它。 notify_one 不会自行释放
    • 好的,我想我明白了。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2015-02-13
    • 2022-01-16
    • 2020-08-09
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多