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

混合条件语句与内存序的代码正确性及相关场景验证

C++内存模型相关问题解答

问题1:disabled原子变量的线程同步正确性

先看目标代码:

std::atomic_bool disabled = true;
int counter1 = 0, counter2 = 1;

// 线程1
while (...)
{
    counter2 = ...;
    if (disabled.load(std::memory_order::acquire) && counter2 > counter1) // #1
    {
        disabled.store(false, std::memory_order::relaxed);
        disabled.notify_one();
    }
}

// 线程2
while (...)
{
    disabled.wait(true, std::memory_order::relaxed);
    // 执行操作
    counter1 = ...;
    disabled.store(true, std::memory_order::release); // #2
}

这段代码可以保证行为正确,#1处的acquire load能与#2处的release store建立同步关系,线程1能看到counter1的正确值,原因如下:

  • 线程2中,counter1 = ... 先行于 disabled.store(true, release)(#2),根据release语义,这个store会将counter1的写入暴露给任何后续读取到该store结果的acquire load。
  • 线程1的#1是acquire load,当它读取到#2写入的true值时,两者之间会建立release-acquire同步关系,线程1因此能看到线程2中counter1的更新。
  • 线程1中disabled.store(false, relaxed)和线程2中disabled.wait(true, relaxed)使用relaxed内存序是可行的:
    • 前者只是临时将disabled设为false以通知线程2,不需要同步其他变量;
    • wait的relaxed内存序仅作用于它内部的load操作,但线程2后续的release store(#2)已经承担了同步counter1的职责,wait的内存序不影响最终的release-acquire同步。

问题2:连续store下的release-acquire同步是否被破坏

看目标代码:

std::atomic_int a = 0;
int x = 0;

// 线程1
x = 1;
a.store(1, std::memory_order::release);
a.store(2, std::memory_order::relaxed);

// 线程2
assert(a.load(std::memory_order::acquire) != 2 || x == 1);

这个断言可能失败,具体分析:

  1. 你的第一种猜想不成立:同一线程内的操作存在先行发生关系,x=1 先行于 a.store(1, release),后者又先行于 a.store(2, relaxed),编译器和CPU不会将第二次store重排到第一次之前。
  2. 你的第二种猜想成立:后续的relaxed store不会“破坏”之前的release-acquire关系,但会导致线程2的acquire load可能看不到release store的结果,从而失去同步:
    • 线程2的acquire load如果读取到2(来自relaxed store),此时该load与线程1的release store(写入1)之间没有同步关系——因为acquire load必须读取到release store的结果才能建立同步。
    • 由于没有同步,线程1中x=1的写入对线程2可能不可见,此时断言会触发(a.load()为2,x为0)。

另外,你提到的seq_cst相关描述,是指当程序中存在非seq_cst的原子操作时,整体的顺序一致性保证会丢失,但这和本次问题中的release-acquire同步是两个独立概念,不影响本次分析。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:56:17