繁体   English   中英

condition_variable并非总是有效

[英]condition_variable not always working

似乎condition_variable notify_one并不总是按应有的方式工作。

struct Task {
    std::mutex mutex;
    std::condition_variable cv;
    std::atomic_bool launch{false};
};
void job(Task& task) {
    std::unique_lock<std::mutex> lock{task.mutex};
    task.cv.wait(lock, [&]{ return task.launch == true; });
}
int main() {
    for (auto i=0 ; i<1000*1000 ; i++) {
        Task task;
        std::thread thread{job, std::ref(task)};
        task.launch = true;
        task.cv.notify_one();
        thread.join();
    }
}

该程序几乎永远不会结束,它在绝大部分时间都永远在循环中停止。 为什么会这样呢?

这里有两个错误:

  • 如果您同步对一个对象的访问,则不需要该对象的原子类型。 您的atomic_bool只会造成开销。
  • 如果要同步对launch标志的访问,则需要在写入前锁定其互斥锁。 您不要在main()这样做。

说明:

  1. main()创建task
  2. main()创建thread
  3. job()锁定互斥锁
  4. job()检查launch ,这是错误的
  5. main()设置launch
  6. main()向CV发出信号,没有人收到
  7. 由于步骤4中的launch值, job()等待CV

通常,第3步和第6步是原子的,因为任何其他线程在锁定互斥体之前都不应接触launch 由于没有发生这种情况,因此允许进行依赖操作的交织,最终导致意外的行为。

不清楚您想要什么,但是您的问题是,可能在主线程有时间调用wait之前,主体意识到launch=truenotify_one() 在这种情况下,您应该知道notify不会延迟,因此您的main将在join时被阻塞,而线程在wait被阻塞。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM