gpt4 book ai didi

multithreading - C++原子内存顺序与线程事件,例如notify()

转载 作者:行者123 更新时间:2023-12-03 13:04:12 27 4
gpt4 key购买 nike

两个线程之间共享原子 bool “就绪”。线程A正在执行某些任务,线程B正在等待A通知。任务完成时,A将“就绪”设置为True。

B有一个等待谓词,测试“就绪”。醒来时,如果“ready”仍为False,则B将返回等待状态。 (这可防止虚假唤醒引起麻烦)

A完成其任务,将“ready”设置为True,然后通知B。

问题:如何保证B将读取(加载)“就绪”为True,而不是较早的False?

atomic<bool> ready = false;

Thread A
do_something();
ready = true;
B_cond_var.notify_one();

Thread B:
B_cond_var.wait( mtx, []() -> bool { return ready == true; } );
do_something(); // <- sometimes doesn't happen

我发现有时B读为“ready”为False,并且从不唤醒。从它的角度来看,这意味着通知是在更新之前进行的,即使在A中订单是更新的,也要先进行通知。

注意:关于内存排序保证,我已经读了太多了,我认为我对读写排序了解得足够多。但是,此问题涉及内存更新和线程通信事件(即通知)的顺序。我找不到有关如何保证订购这些产品的直接答案。

参见例如:
http://www.developerfusion.com/article/138018/memory-ordering-for-atomic-operations-in-c0x/

http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/

Memory ordering behavior of std::atomic::load

另请参阅C++ 11标准第29.3节

更新:很抱歉,上面的内容只是伪代码,是从更大的主体中分解而来的,我已经省略了一些不会引起问题的内容,例如条件变量上存在互斥量。该工作代码展示了所描述的变量更新的重新排序,并且大约每400天运行时通知一次-实际上,每天运行3-4次。这实际上正在发生。

最佳答案

如果使用条件变量保护原子变量,则不需要原子变量。但是,条件变量需要互斥体,在此代码中我看不到互斥体。您的lambda missess返回声明也是如此。

正确使用的条件变量将为您提供所需的结果。

内存排序在这里完全无关紧要,因为所有Posix线程同步原语都施加了完整的内存障碍。

关于multithreading - C++原子内存顺序与线程事件,例如notify(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36505804/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com