关于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是不正确的。

相关推荐
yezipi耶不耶1 小时前
Rust入门之并发编程基础(一)
开发语言·后端·rust
木子.李3471 小时前
数据结构-算法学习C++(入门)
数据库·c++·学习·算法
南瓜胖胖2 小时前
【R语言编程绘图-plotly】
开发语言·plotly·r语言
半青年2 小时前
IEC61850规约客户端软件开发实战(第二章)
java·c++·qt·网络协议·c#·信息与通信·iec61850
@Turbo@2 小时前
【QT】在QT6中读取文件的方法
开发语言·数据库·qt
_extraordinary_3 小时前
Java 异常
java·开发语言
moz与京3 小时前
【数据结构】字符串操作整理(C++)
开发语言·数据结构·c++
招财进宝。。3 小时前
c# 获取电脑 分辨率 及 DPI 设置
开发语言·c#·电脑
无处不在的海贼3 小时前
小明的Java面试奇遇之:支付平台高并发交易系统设计与优化[特殊字符]
java·开发语言·面试
居居飒3 小时前
深入理解 JDK、JRE 和 JVM 的区别
java·开发语言·jvm