关于std::memory_order_consume

原文:https://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/

翻译:C++11中memory_order_consume的目的

https://blog.csdn.net/netyeaxi/article/details/80718781

文章中有这样一个例子:

复制代码
g = Guard.load(memory_order_consume);
if (g != nullptr)
    p = *g;

既然g已经表明了代码级别的依赖,为什么还需要memory_order_consume,而不可以直接memory_order_relaxed呢?

搜了一下这里有个解释,但是它似乎没有说清楚:https://stackoverflow.com/questions/38280633/c11-the-difference-between-memory-order-relaxed-and-memory-order-consume

其实也比较简单,先看一下memory_order_release的规则(中英文对照方便理解):https://en.cppreference.com/w/cpp/atomic/memory_order

有此内存定序的存储操作进行释放操作:当前线程中的读或写不能被重排到此存储之后。

  1. 当前线程的所有写入,可见于获得该同一原子变量的其他线程(见下方释放-获得定序)
  2. 并且对该原子变量的带依赖写入变得对于其他消费同一原子对象的线程可见(见下方释放-消费定序)。

A store operation with this memory order performs the release operation: no reads or writes in the current thread can be reordered after this store.

  1. All writes in the current thread are visible in other threads that acquire the same atomic variable (see Release-Acquire ordering below)
  2. writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic (see Release-Consume ordering below).

注意第二条:在其他线程,使用consume能保证该原子变量的带依赖写入(文中的g)可见。换言之relaxed不能保证这一点。

也就是:

复制代码
Payload = 42;
Guard.store(&Payload, memory_order_release);

在另一个线程看起来可能是:

复制代码
Guard.store(&Payload, memory_order_release);
Payload = 42;

另外我们也能得到这样的结论:只使用memory_order_release,而不配合使用acquire或consume或其他更严格约束的话,对其他线程来说是没有意义的。

再推而广之,所有的memory_order都要在多个线程配合使用,才能影响变量在线程之间的可见性。根据这一点,也能理解为什么relaxed是不正确的。

相关推荐
czy87874752 分钟前
深入了解 C++ 中的 `std::bind` 函数
开发语言·c++
消失的旧时光-19436 分钟前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
yq1982043011567 分钟前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端
一个public的class8 分钟前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
Jinkxs10 分钟前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&11 分钟前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
我在人间贩卖青春11 分钟前
C++之继承的方式
c++·private·public·protected·继承方式
BD_Marathon41 分钟前
设计模式——依赖倒转原则
java·开发语言·设计模式
devmoon1 小时前
在 Polkadot Runtime 中添加多个 Pallet 实例实战指南
java·开发语言·数据库·web3·区块链·波卡
Evand J1 小时前
TDOA(到达时间差)的GDOP和CRLB计算的MATLAB例程,论文复现,附参考文献。GDOP:几何精度因子&CRLB:克拉美罗下界
开发语言·matlab·tdoa·crlb·gdop