std::atomic::load默认使用std::memory_order_seq_cst,但性能开销大;应根据同步需求选用acquire/release或relaxed;store()与operator=内存序不同;compare_exchange_weak需分别指定成功和失败的内存序。
std::atomic::load 默认用的是 std::memory_order_seq_cst
绝大多数情况下,
不传
参数,就等价于
。这不是“最安全”的选择,而是 C++ 标准规定的默认行为:它强制所有线程看到的操作顺序全局一致,代价是可能触发全内存栅栏(full fence),在弱一致性架构(如 ARM、RISC-V)上开销明显。
如果你只是读一个标志位(比如
),且写端用的是
,那读端用
就足够了——既保证数据可见性,又避免不必要同步开销。
不要默认以为 “seq_cst 就是必须的”,尤其在高频轮询或性能敏感路径中
可用于计数器累加、统计类场景,但不能用于同步逻辑(比如等待某个状态)
用
时若没指定 order,编译器不会报错,但可能掩盖同步漏洞
store() 和 operator= 的内存序行为不完全等价
明确支持传入任意
,而
固定使用
。这意味着:
想用
发布数据(如写完
后设
),必须写
,不能写
看起来简洁,但会隐式引入更强的顺序约束,可能拖慢性能,也容易让后续维护者误判同步意图
代码审查时,
和
是信号:这里有意图地控制内存序;
和隐式转换则缺乏这种表达力
load() 配合 acquire、store() 配合 release 才构成同步对
单个
或
没有意义——它们必须成对出现,跨线程才能建立 happens-before 关系。
立即学习
“
C++免费学习笔记(深入)
”;
C知道
CSDN推出的一款AI技术问答工具
下载
典型模式:
release store 保证其之前的普通写(
)不会被重排到它之后
acquire load 保证其之后的普通读(
)不会被重排到它之前
两个操作通过同一个原子变量(
)关联,才构成同步点
如果读端用了
,即使写端是
,也不能保证看到
的新值
compare_exchange_weak 的 memory_order 参数要分两组传
是 RMW 操作,它内部包含一次 load 和一次 store,所以需要两个内存序参数:
成功时的内存序(即 store 部分):第二个参数
失败时的内存序(即 load 部分):第三个参数
常见写法:
漏掉第三个参数会导致编译失败(不是默认值)
多数场景下,
用
足够;
用
可支持后续同步
别把两个参数都设成
——除非你清楚自己在放弃同步语义
实际写多线程代码时,最容易忽略的不是语法,而是“哪个操作和哪个操作构成同步对”。
和
的内存序必须跨线程配对理解,而不是孤立看单个调用。
load()orderload(std::memory_order_seq_cst)std::atomic ready store(true, std::memory_order_release)load(std::memory_order_acquire)std::memory_order_relaxedload()store()std::memory_orderoperator=std::memory_order_seq_cststd::memory_order_releasedataready = trueready.store(true, std::memory_order_release)ready = trueoperator=store()load()=load(std::memory_order_acquire)store(std::memory_order_release)
// 线程 A(生产者)
data = 42; // 普通写
ready.store(true, std::memory_order_release); // release store
// 线程 B(消费者)
while (!ready.load(std::memory_order_acquire)) { / 等待 / } // acquire load
// 此处能安全读 data == 42
data = 42datareadyrelaxedreleasedatacompare_exchange_weak()successfailure
std::atomic counter{0};
int expected = 0;
counter.compare_exchange_weak(expected, 1,
std::memory_order_acq_rel, // 成功:既是 acquire(读旧值)又是 release(写新值)
std::memory_order_acquire); // 失败:只做 acquire load
failurestd::memory_order_acquiresuccessstd::memory_order_acq_relrelaxedload()store()