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

该传递性happens-before用例需顺序一致性还是仅需释放/获取语义?

关于Herb Sutter《Atomic Weapons》幻灯片的内存序疑问

以下内容来自Herb Sutter《Atomic Weapons》演讲第19页幻灯片:原示例使用std::memory_order_seq_cst保证线程3中的assert()不会失败,现疑问改用release/acquire语义是否同样可行。

原代码(顺序一致性)

int g{0}; // normal int
std::atomic<int> x{0}, y{0}; // atomics

void thread1() {
    g = 1;
    x.store(1, std::memory_order_seq_cst);
}

void thread2() {
    if(x.load(std::memory_order_seq_cst) == 1)
        y.store(1, std::memory_order_seq_cst);
}

void thread3() {
    if(y.load(std::memory_order_seq_cst) == 1)
        assert( g == 1 );
}

改写代码(释放/获取语义)

int g{0}; // normal int
std::atomic<int> x{0}, y{0}; // atomics

void thread1() {
    g = 1;  // A
    x.store(1, std::memory_order_release);
}

void thread2() {
    if(x.load(std::memory_order_acquire) == 1)
        y.store(1, std::memory_order_release);
}

void thread3() {
    if(y.load(std::memory_order_acquire) == 1)
        assert( g == 1 );  // B
}

疑问

  • Q1:由于没有其他线程写入g,//A 是否能保证在//B之前发生,从而让断言有效?
  • Q2:是否误解了幻灯片的主旨,或是幻灯片存在错误?

解答

针对Q1

断言可以保证有效。根据C++内存模型规则:

  1. 线程1中,g=1(标记A)happens-before x.store(1, release)——同一线程内操作按程序顺序形成天然的happens-before关系,且release语义会阻止A被重排到store之后。
  2. 若线程2中x.load(acquire)读到1,则x.store(release)与x.load(acquire)形成synchronizes-with关系,进而线程2中的y.store(1, release) happens-after x.load(acquire)。
  3. 若线程3中y.load(acquire)读到1,则y.store(release)与y.load(acquire)形成synchronizes-with关系,进而assert(g==1)(标记B)happens-after y.load(acquire)。

通过这一完整同步链条,A对g的写入对B完全可见,且没有其他线程修改g,因此g的值必然为1,断言不会触发。

针对Q2

既没有误解幻灯片主旨,也不存在幻灯片错误。幻灯片使用seq_cst是因为它是最直观的强一致性内存序,能保证所有原子操作全局有序,适合作为基础示例展示线程同步的正确性。而release/acquire是更轻量的内存序,在这个场景中,我们只需要构建线程1→线程2→线程3的单向同步链条,不需要全局顺序一致性,因此release/acquire完全可以满足需求,同样能保证断言不失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:41:11