You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何理解C++20中顺序一致性排序的变更及示例疑惑

P0668R5对C++顺序一致性排序的修改及示例解析

示例代码与观测结果

x和y的初始值为0,三个线程的执行代码如下:

// 线程1:
x.store(1, std::memory_order_seq_cst); // A
y.store(1, std::memory_order_release); // B
// 线程2:
r1 = y.fetch_add(1, std::memory_order_seq_cst); // C
r2 = y.load(std::memory_order_relaxed); // D
// 线程3:
y.store(3, std::memory_order_seq_cst); // E
r3 = x.load(std::memory_order_seq_cst); // F

根据P0668R5提案,允许观测到结果:r1=1、r2=3、r3=0,但该结果在修改前的C++标准中是不被允许的。

旧标准的矛盾点

当前标准不允许上述结果:所有std::memory_order_seq_cst访问必须处于单一全序中,该全序需满足F在A之前(因为F未观测到A的存储),A必须在C之前(因为A先行于C),C必须在E之前(因为fetch_add未观测到E的存储,而线程2的加载强制E处于修改顺序的末尾)。但这是不允许的,因为标准要求先行顺序与顺序一致性排序一致,而全序末尾的E先行于开头的F。

C++20的修改方案

C++20通过修改强先行关系(strongly happens-before)的定义解决了这一矛盾:旧标准中的先行关系被重命名为普通先行关系,新的强先行关系对约束条件做了收紧。根据新规则,尽管A普通先行于C,但A并不强先行于C,因此A不需要在seq_cst的单一全序中排在C之前。

疑问与待解释点

我对修改后的结果存在疑问:根据cppreference,该示例中std::memory_order_seq_cst的单一全序为C-E-F-A(不清楚原因)。但根据先行规则,A仍先行于C,因此A的副作用应对C可见。这是否意味着在线程2观测到的修改顺序中A排在C之前?若是,是否意味着所有线程观测到的单一全序不一致?恳请详细解释上述示例。


内容的提问来源于stack exchange,提问作者Pluto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 12:36:18