通过严格更强或同等强,我的意思是任何
acq_rel
都可以替换为seq_cst
,并且这不会削弱acq_rel
语义提供的任何保证。
当我从字面上阅读 cpp reference 时:
对该内存的读取-修改-写入操作 order 既是获取操作又是释放操作。没有记忆 当前线程中的读取或写入可以在之前重新排序 加载,也不在存储之后。释放的其他线程中的所有写入 相同的原子变量在修改之前是可见的 修改在获取相同原子的其他线程中是可见的 变量。memory_order_acq_rel
使用此内存顺序执行加载操作 获取操作,存储执行释放操作,以及 读-修改-写执行获取操作和释放操作 操作,加上存在一个总顺序,其中所有线程 以相同的顺序观察所有修改(参见 以下顺序一致)。memory_order_seq_cst
我注意到
seq_cst
缺少一个出现在acq_rel
中的句子:
当前线程中的内存读取或写入在加载之前或存储之后都不能重新排序。
参考文献进一步提到(在不同的部分):
在许多情况下,
原子操作相对于同一线程执行的其他原子操作是可重新排序的。memory_order_seq_cst
这些让我觉得
acq_rel
是双向障碍,而seq_cst
根本就不是障碍。另一方面,我读过的所有文字都说seq_cst
提供了更有力的保证。我不知道 1) seq_cst
是否也是像 acq_rel
一样的障碍,以及 2) 将任何 acq_rel
“升级”为 seq_cst
是否安全。
是的,
seq_cst
严格来说更强。
在许多情况下,
原子操作相对于同一线程执行的其他原子操作是可重新排序的。memory_order_seq_cst
这不是特定于
seq_cst
,所有原子操作都可以像这样重新排序,除了:
单个变量上的操作永远不能相对于彼此重新排序,只能相对于其他变量重新排序。
seq_cst
操作之间无法相对重新排序。
我注意到
缺少一个出现在seq_cst
中的句子:acq_rel
当前线程中的内存读取或写入在加载之前或存储之后都不能重新排序。
该标准没有就重新排序进行措辞。它只说明哪些原子操作彼此同步。 (如果 A 与 B 同步,则 A 之前发生的所有操作将先于 B 之前发生的所有操作发生。)
[atomics.order]/1
表示release
和seq_cst
写入都是“释放操作”,acquire
和seq_cst
读取都是“获取操作”。
[atomics.order]/2
表示“释放操作”与“获取操作”同步。