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

C++各类memory_order含义通俗解读及应用疑问

C++原子操作memory_order通俗解析

在多线程编程中,原子操作的memory_order决定了内存可见性和指令重排规则,合理选择可以在保证正确性的前提下避免memory_order_seq_cst带来的性能损耗。下面逐个拆解每个规则的通俗含义:

memory_order_relaxed

这是约束最弱的内存顺序,只保证原子操作本身的原子性,完全不限制编译器和CPU对该操作前后指令的重排,也不保证跨线程的内存可见性顺序。

比如你给出的例子:

// 全局变量
atomic<int> x, y;

// 线程1
x.store(17, memory_order_relaxed);
y.store(37, memory_order_relaxed);

// 线程2
cout << y.load(memory_order_relaxed) << " ";
cout << x.load(memory_order_relaxed) << endl;

线程1的两个store操作可能被重排,线程2的两个load操作也可能乱序执行。极端情况下,线程2可能先读到y=37(线程1的y.store已完成),但此时线程1的x.store还没同步到线程2的内存,所以读到x=0,出现输出37 0的情况。

memory_order_release & memory_order_acquire

这是一对配套使用的规则,专门用来建立线程间的同步关系:

  • memory_order_release:用于原子写操作,保证该操作之前的所有普通写操作,都会同步到其他线程;同时,编译器/CPU不会把release之前的指令重排到release之后。
  • memory_order_acquire:用于原子读操作,保证该操作之后的所有普通读操作,都能看到对同一个原子变量执行release写操作的线程的所有前置写;同时,编译器/CPU不会把acquire之后的指令重排到acquire之前。

还是你的例子,修改内存顺序后:

// 全局变量
atomic<int> x, y;

// 线程1
x.store(17, memory_order_release);
y.store(37, memory_order_release);

// 线程2
cout << y.load(memory_order_acquire) << " ";
cout << x.load(memory_order_acquire) << endl;

如果线程2读到y=37(通过acquire load),说明线程1的y.store(release)已经完成,而线程1中y.store之前的x.store(17)必然已经同步到内存,所以线程2读x的时候一定能读到17,绝不会出现37 0的输出。

memory_order_consume

这是acquire的轻量级版本,它只针对依赖于原子变量的后续操作做约束:当线程用consume读取一个原子变量后,只有那些直接或间接依赖该变量的操作,不会被重排到load之前,且能看到release写该变量的线程的前置相关操作。

比如原子变量是一个指针,线程A用release写指针指向一块数据,线程B用consume读指针,那么线程B中访问该指针指向数据的操作,能看到线程A在写指针前对这块数据的修改,但线程B中不依赖该指针的操作仍可能被重排。不过目前多数编译器会把consume等同于acquire处理(因为实现依赖关系的成本太高),但概念上要明确它是针对依赖链的弱同步。

memory_order_acq_rel

这个规则用于既读又写的原子操作(比如fetch_add、exchange这类),它同时具备acquire和release的特性:

  • 作为读操作时,等价于acquire:能看到所有对该原子变量执行release写操作的线程的前置写。
  • 作为写操作时,等价于release:自己的前置写会同步到所有后续对该原子变量执行acquire读的线程。

memory_order_seq_cst

这是最严格的内存顺序,所有线程看到的原子操作顺序完全一致,相当于所有原子操作都在一个全局的"总序"队列里执行。它会强制CPU执行内存栅栏,保证全局顺序一致,但性能开销极大——在很多场景下,它的性能甚至不如互斥锁,所以只有当你需要全局统一的操作顺序时才使用,否则优先选择更轻量的规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:53:15