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

为何Relaxed内存序在该C++示例中表现与Sequential Consistent一致?

关于C++ Relaxed内存序与Sequential Consistent表现一致的疑问

我测试了cppreference和《C++ Concurrency in Action》(Anthony Williams著)清单5.4中的示例,将所有memory_order_seq_cst替换为memory_order_relaxed后,上万次测试里assert都没有触发。但cppreference明确说明“任何其他内存序都可能触发assert,因为线程c和d可能以相反顺序观察到原子变量x和y的变化”,Anthony也提到“该约束不会延伸到使用relaxed内存序的原子操作线程”,这和我的测试结果矛盾。

我的问题是:为什么Relaxed内存序在这个示例中表现和Sequential Consistent内存序完全一致?

测试步骤

# 编译
c++ example.cc

# 重复测试100000次
for i in {1..100000}; do ./a.out; done;
# 所有测试均成功,无abort情况

测试代码

#include <thread>
#include <atomic>
#include <cassert>
 
std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};
 
void write_x()
{
    x.store(true, std::memory_order_relaxed);
}
 
void write_y()
{
    y.store(true, std::memory_order_relaxed);
}
 
void read_x_then_y()
{
    while (!x.load(std::memory_order_relaxed))
        ;
    if (y.load(std::memory_order_relaxed)) {
        ++z;
    }
}
 
void read_y_then_x()
{
    while (!y.load(std::memory_order_relaxed))
        ;
    if (x.load(std::memory_order_relaxed)) {
        ++z;
    }
}
 
int main()
{
    std::thread a(write_x);
    std::thread b(write_y);
    std::thread c(read_x_then_y);
    std::thread d(read_y_then_x);
    a.join(); b.join(); c.join(); d.join();
    assert(z.load() != 0);  // 从未触发
}

问题解析

首先要明确:C++内存模型定义的是允许出现的行为,不是一定会出现的行为。cppreference和书中的表述是说relaxed内存序下assert有可能触发,而不是必然触发。你的测试没触发,只是没碰到那个概率极低的执行路径而已。

具体来说,这种“反向观察”的情况需要满足几个极端条件:

  1. 线程c看到x被设置为true,但此时y的更新还没同步到它的缓存;
  2. 线程d看到y被设置为true,但此时x的更新还没同步到它的缓存;
  3. 两个线程各自完成后续操作后,z的值依然是0,最终触发assert。

现代CPU的缓存同步机制(比如MESI协议)以及编译器的优化策略,会让这种极端情况很难出现。尤其是在x86架构下,CPU本身对内存操作有较强的一致性保证(默认接近seq_cst的顺序一致性,仅允许store-load重排),而你的代码里没有store-load的场景,所以relaxed和seq_cst的表现几乎一致。

另外,测试次数多不代表能覆盖所有可能的执行路径。这种竞态条件的触发依赖于CPU调度、缓存刷新的精确时机,可能需要百万甚至千万次测试才有可能碰到一次,或者在特定的弱一致性架构(比如部分老款ARM)上更容易重现。

总结:relaxed内存序确实允许assert触发的情况存在,只是你的测试环境和次数还没碰到而已,这和内存模型的定义并不矛盾。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:00:58