C++内存序memory_order

C++ 原子操作提供 6种内存序(memory_order),分别控制编译器和 CPU 如何对内存操作进行重排序优化,确保并发程序在多线程之间的行为可控、正确。


所有内存序(memory_order)

C++ 中 std::memory_order 的 6 种选项如下:

枚举值中文名简要说明
memory_order_relaxed放松序不保证任何顺序,只保证原子性
memory_order_consume消费序(已废弃趋势)数据依赖同步,仅限依赖关系(不推荐使用)
memory_order_acquire获取序保证本线程之后的操作不会被重排到原子操作前
memory_order_release释放序保证本线程之前的操作不会被重排到原子操作后
memory_order_acq_rel获取 + 释放序同时保证 acquire + release 的效果,适用于 read-modify-write 操作
memory_order_seq_cst顺序一致性(默认)最强的保证:所有线程中看起来像是全局有序执行


简明图解理解(线程内操作顺序)

  • relaxed: 无序(性能最好,但易出错)

  • acquire: 不能把后面的操作移到前面

  • release: 不能把前面的操作移到后面

  • acq_rel: 二者兼具

  • seq_cst: 所有线程观察到的执行顺序一致


常见用法示例对比

默认顺序一致性 memory_order_seq_cst

#include <atomic>

std::atomic<int> x{0};  // 初始化为 0
x.store(10);                  // store (默认 seq_cst)
int v = x.load();             // load (默认 seq_cst)


顺序一致性:多线程中所有原子操作全局有序,易于理解但开销较大。 

放松序 memory_order_relaxed

#include <atomic>

std::atomic<int> x{0};  // 初始化为 0
// 线程 A
x.store(10, std::memory_order_relaxed);  // 原子写,不保证顺序

// 线程 B
int value = x.load(std::memory_order_relaxed);  // 原子读,不保证看到更新

获取 / 释放语义:典型锁实现方式

#include <atomic>

std::atomic<bool> flag{false};  // 默认未设置

// 线程 A:写线程
data = 123;  // 假设 data 是共享变量
flag.store(true, std::memory_order_release);  // 发布 data 已准备好

// 线程 B:读线程
if (flag.load(std::memory_order_acquire)) {
    // 这里看到 flag == true
    // 根据 acquire 语义:保证看到的 data = 123
    std::cout << data << std::endl;
}

这就是经典的 “写线程 release,读线程 acquire” 搭配,确保读线程看到完整写入的数据。


atomic_flag 使用场景建议的 memory_order

操作类型推荐的 memory_order
flag.test_and_setstd::memory_order_acquire
flag.clearstd::memory_order_release


小结

序名用途是否有序性能说明
relaxed最快的,不同步🔥🔥🔥仅原子性,无顺序
acquire用于加锁✅(后有序)🔥🔥加锁读
release用于解锁✅(前有序)🔥🔥解锁写
acq_rel读写同时🔥用于 fetch_add 等
seq_cst最强顺序保证✅✅✅🐢默认值,全局有序
consume基本弃用不推荐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值