我是不是需要内存屏障来访问已完成的线程修改的内存?

Posted

技术标签:

【中文标题】我是不是需要内存屏障来访问已完成的线程修改的内存?【英文标题】:Do I need memory barrier for accessing memory modified by the thread that finished?我是否需要内存屏障来访问已完成的线程修改的内存? 【发布时间】:2017-08-23 10:48:32 【问题描述】:

[以下,C++ 术语] 我有一个线程 A 和线程 B 共享对整数值 P 的访问。线程 A 初始化这个值并在运行时更新它。然后线程 A 完成。线程 B 等待线程 A 完成(标准 OS API 调用,无论使用什么操作系统)并想要读取 P。 线程 B 是否需要内存屏障来读取线程 A 最后设置的一致的 P 值?是否有可能当 OS API 说“线程 A 完成”时,它修改的内存更改对其他线程不可见? 请注意,只有一个 线程在此处写入值,这可能会或可能不会将此问题与之前提出的“Is there an implicit memory barrier with synchronized-with relationship on thread::join?”区分开来。我的直觉告诉我答案应该是一样的,但是......

【问题讨论】:

这听起来像是 `std::future 的工作。 从阅读 this 开始,我会说是的 - .join() 确实同步,并且您不需要内存屏障。但是这段文字不是写给普通人解释的,所以我会把答案留给其他人。也可能是 ***.com/questions/12444891/… 的副本 【参考方案1】:

join 与调用join 的线程同步。也就是说,当B 调用A.join() 时,A 进行的所有写入都将对B 可见。

你可以认为这是A在完成时执行std::atomic_thread_fence(memory_order_release)Bstd::atomic_thread_fence(std::memory_order_acquire加入时执行std::atomic_thread_fence(std::memory_order_acquire

线程B是否需要内存屏障

是的,但它们隐含在 join 中,您不必编写它们。

是否有可能当 OS API 说“线程 A 完成”时,它修改的内存更改对其他线程不可见?

join 的调用者以外的线程将需要额外的同步,例如std::condition_variablestd::atomic_thread_fence(std::memory_order_acquire);

【讨论】:

以上是关于我是不是需要内存屏障来访问已完成的线程修改的内存?的主要内容,如果未能解决你的问题,请参考以下文章

内存屏障

RCU机制及内存优化屏障

谈乱序执行和内存屏障

为啥需要内存屏障?

谈乱序执行和内存屏障

Java中内存屏障的行为