导读:本期聚焦于小伙伴创作的《C++中的memory_order是什么?如何规定多线程下的内存可见性顺序》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的memory_order是什么?如何规定多线程下的内存可见性顺序》有用,将其分享出去将是对创作者最好的鼓励。

C++中的memory_order是C++11引入的原子操作内存顺序属性,用于定义多线程环境下原子操作的执行顺序和内存可见性规则,解决不同线程对共享数据操作的顺序不确定性问题。它和std::atomic类配合使用,让开发者可以在保证程序正确性的同时,根据场景选择合适的内存约束,平衡性能与正确性。

C++中的memory_order是什么?如何规定多线程下的内存可见性顺序

memory_order的核心作用

在多线程场景中,编译器和CPU可能会对指令进行重排序,同时不同CPU核心有各自的内存缓存,这会导致一个线程对共享变量的修改,其他线程不能立即看到,甚至出现操作顺序和代码编写顺序不一致的情况。memory_order就是用来约束这种重排序行为和缓存同步规则的,它告诉编译器和CPU当前原子操作需要什么样的内存可见性保证。

memory_order的常见取值

C++标准定义了6种memory_order取值,每种对应不同的内存顺序约束,具体如下:

取值含义
memory_order_relaxed宽松顺序,只保证原子操作的原子性,不保证任何内存顺序和可见性约束,性能最高
memory_order_consume消费顺序,当前原子操作的结果,对依赖该结果的后续操作可见,目前多数编译器将其当作acquire处理
memory_order_acquire获取顺序,搭配release使用,当前操作之后的读写操作,不能被重排序到当前操作之前,且能看到release操作之前的所有写入
memory_order_release释放顺序,搭配acquire使用,当前操作之前的读写操作,不能被重排序到当前操作之后,且会被acquire操作看到
memory_order_acq_rel获取释放顺序,同时具有acquire和release的特性,用于读-修改-写类型的原子操作
memory_order_seq_cst顺序一致顺序,最严格的约束,所有使用该顺序的原子操作全局有一个一致的执行顺序,默认的内存顺序

不同memory_order的使用示例

1. memory_order_seq_cst示例

这是默认的内存顺序,所有原子操作全局顺序一致,适合对顺序要求严格的场景:

#include <atomic>
#include <thread>
#include <iostream>

std::atomic<int> x(0);
std::atomic<int> y(0);

void thread1() {
    x.store(1, std::memory_order_seq_cst); // 原子写x,顺序一致
    y.store(1, std::memory_order_seq_cst); // 原子写y,顺序一致
}

void thread2() {
    while (y.load(std::memory_order_seq_cst) == 0) { // 原子读y,顺序一致
        // 等待y被修改
    }
    std::cout << "x的值: " << x.load(std::memory_order_seq_cst) << std::endl; // 原子读x,顺序一致
}

int main() {
    std::thread t1(thread1);
    std::thread t2(thread2);
    t1.join();
    t2.join();
    return 0;
}

上述代码中,由于使用了顺序一致的内存顺序,线程2看到y为1的时候,一定能看到x已经被修改为1,输出结果一定是1。

2. memory_order_acquire和memory_order_release示例

这两个顺序通常配对使用,实现线程间的同步,比顺序一致的性能更好:

#include <atomic>
#include <thread>
#include <iostream>

std::atomic<int> flag(0);
int data = 0;

void producer() {
    data = 42; // 修改共享数据
    // release操作,确保data的修改在flag写之前完成,且对acquire可见
    flag.store(1, std::memory_order_release);
}

void consumer() {
    // acquire操作,确保flag的读之后的操作不会被重排序到前面,且能看到release之前的所有写入
    while (flag.load(std::memory_order_acquire) == 0) {
        // 等待flag被修改
    }
    std::cout << "读取到的data值: " << data << std::endl;
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join();
    t2.join();
    return 0;
}

这里producer中flag的release操作,会保证data的修改先于flag的修改被提交,consumer中flag的acquire操作,会保证读到flag为1的时候,一定能看到data已经被修改为42,输出结果一定是42。

3. memory_order_relaxed示例

宽松顺序只保证原子性,不保证可见性顺序,适合不需要同步的场景:

#include <atomic>
#include <thread>
#include <iostream>

std::atomic<int> counter(0);

void increment() {
    for (int i = 0; i < 1000; i++) {
        // 宽松顺序,只保证自增操作是原子的,不保证顺序
        counter.fetch_add(1, std::memory_order_relaxed);
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << "最终counter值: " << counter << std::endl;
    return 0;
}

这里counter的自增只需要保证原子性,不需要不同线程之间的顺序约束,使用relaxed顺序就可以满足需求,同时性能更好,最终counter的值一定是2000。

memory_order的选择建议

  • 如果不确定该用哪种内存顺序,优先选择默认的memory_order_seq_cst,它最安全,不容易出错。
  • 如果需要实现两个线程之间的同步,比如生产者消费者场景,优先选择memory_order_acquire和memory_order_release配对使用,性能比顺序一致更好。
  • 如果原子操作不需要和其他线程同步,只需要保证自身的原子性,比如计数器场景,可以选择memory_order_relaxed。
  • memory_order_consume目前实际使用中较少,多数编译器会将其等同于acquire处理,不建议优先使用。

注意事项

memory_order只对有原子操作的内存顺序有约束,对非原子变量的操作没有约束,因此多线程中共享的非原子变量必须通过原子操作或者互斥锁来保护,不能依赖memory_order来保证非原子变量的可见性。另外,错误的内存顺序选择可能导致程序出现数据竞争和未定义行为,使用前需要充分理解不同取值的含义。

memory_order多线程内存可见性原子操作修改时间:2026-06-27 06:24:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。