C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ memory_order

C++内存序memory_order的具体操作

作者:Damon_X

C++原子操作提供6种内存序,用于控制多线程内存重排序,确保并发正确性,下面就来具体介绍一下,感兴趣的可以了解一下

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顺序一致性(默认)最强的保证:所有线程中看起来像是全局有序执行

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

常见用法示例对比

默认顺序一致性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基本弃用不推荐

到此这篇关于C++内存序memory_order的具体操作的文章就介绍到这了,更多相关C++ memory_order内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文