C++ 无锁编程:原子操作、内存顺序与生产者-消费者模型的实战指南
目录1六大内存序2原子操作2.1原子操作的核心操作基础操作store 和 load3利用内存模型和原子操作的生产者消费者模型设计1六大内存序内存顺序类型核心特点memory_order_relaxed宽松无同步只保证原子性不保证顺序。不引入同步屏障允许编译器和 CPU 任意重排memory_order_consume消费已过时依赖当前原子变量的后续操作不被重排到它之前。不推荐使用编译器通常降级为 acquirememory_order_acquire获取读屏障该原子读操作之后的所有读写操作都不能重排到该操作之前。memory_order_release释放写屏障该原子写操作之前的所有读写操作都不能重排到该操作之后memory_order_acq_rel获取-释放读写屏障同时具备 acquire 和 release 效果用于 Read-Modify-Write 操作如 exchange。memory_order_seq_cst顺序一致性最强全局所有线程看到统一的修改顺序最强最直观但性能开销最大。1memory_order_release 释放----写屏障 可以理解为原子操作的时候进行写操作在写完释放给别的线程读之前必须把此线程在自身缓冲区写的数据全部同步到 公共的缓存中“线程在执行 Release 写操作时必须确保本线程在 Release 之前发生的所有写操作都已经对其它核心可见即排空到共享缓存然后才允许执行 Release 这个写操作本身。”2memory_order_acquire 获取----读屏障 可以理解为必须先将公共区的数据都读完之后在进行其他的操作比如写操作。2原子操作原子操作Atomic Operation是指不可被中断的一个或一系列操作。在多线程环境中原子操作要么全部执行完成要么完全不执行不会出现执行到一半被其他线程干扰的情况。2.1原子操作的核心操作基础操作store 和 load操作函数原型允许的内存顺序写入void store(T desired, memory_order order seq_cst)relaxed, release, seq_cst读取T load(memory_order order seq_cst) constrelaxed, acquire, seq_cststd::atomicintvalue{0};// store 操作value.store(42);// 默认 seq_cstvalue.store(100,std::memory_order_release);// 显式指定 releasevalue.store(1,std::memory_order_relaxed);// 最弱的顺序// load 操作int xvalue.load();// 默认 seq_cstint yvalue.load(std::memory_order_acquire);// 显式指定 acquireint zvalue.load(std::memory_order_relaxed);// 最弱的顺序store 不能使用 memory_order_acquire 或 memory_order_acq_relload 不能使用 memory_order_release 或 memory_order_acq_rel操作函数原型说明交换T exchange(T desired, memory_order order seq_cst)用新值替换旧值返回旧值CAS弱bool compare_exchange_weak(T expected, T desired, …)可能虚假失败适合循环CAS强bool compare_exchange_strong(T expected, T desired, …)不会虚假失败算术T fetch_add(T arg, memory_order order seq_cst)加、减、与、或、异或std::atomicintcounter{10};// exchange交换并返回旧值int oldcounter.exchange(20);// old 10, counter 20// fetch_add原子加int previouscounter.fetch_add(5);// previous 20, counter 25// compare_exchangeCASCompare-And-Swapint expected25;if(counter.compare_exchange_strong(expected,100)){// 如果 counter 当前是 25替换为 100expected 不变std::cout替换成功counter 100std::endl;}else{// 替换失败expected 被更新为 counter 的实际值std::cout替换失败当前值为expectedstd::endl;}特性compare_exchange_weakcompare_exchange_strong虚假失败✅ 可能即使相等也返回 false❌ 不会相等一定返回 true性能更快某些平台可用 LL/SC 优化稍慢需要重试处理典型用法循环中while weak单次检查返回值bool成功/失败bool成功/失败// ✅ weak 的正确用法在循环中重试std::atomicintvalue{0};int expected0;while(!value.compare_exchange_weak(expected,100,std::memory_order_acq_rel)){// 失败时 expected 被更新为实际值// 这里可以加一个最大重试次数限制}// ✅ strong 的典型用法单次检查int expected0;if(value.compare_exchange_strong(expected,100,std::memory_order_acq_rel)){// 成功处理}3利用内存模型和原子操作的生产者消费者模型设计#includeiostream#includethread#includeatomicstd::atomicintcount{0};// 共享整形变量初始为 0绝对主角std::atomicboolready{false};// 同步标志true有货待消费false已消费// 生产者count 不断加一 voidproducer(){for(int i1;i10;i){// ① 直接修改 count加一操作// 使用 release保证这次写入完成之前之前的所有操作都已完成count.store(i,std::memory_order_release);// ② 通知消费者count 已经更新快来打印// 必须用 release保证 count 的写入在通知之前可见ready.store(true,std::memory_order_release);// ③ 等待消费者打印完成等待 ready 被改回 falsewhile(ready.load(std::memory_order_acquire)){// 自旋等待CPU 会忙等}}}// 消费者打印 count 的当前值 voidconsumer(){for(int i1;i10;i){// ① 等待生产者通知等待 ready 变成 truewhile(!ready.load(std::memory_order_acquire)){// 自旋等待}// ② 读取 count 的最新值并打印// 用 acquire 保证读到的 count 一定是生产者 release 写进去的最新值int valuecount.load(std::memory_order_acquire);std::cout消费者打印: count valuestd::endl;// ③ 告诉生产者我已经打印完了你可以生产下一个了// 用 release 保证“打印完成”这个动作在改 ready 之前完成ready.store(false,std::memory_order_release);}}intmain(){std::threadt1(producer);std::threadt2(consumer);t1.join();t2.join();return0;}

相关新闻

OpenCompass L2评测实践与书生大模型能力验证

OpenCompass L2评测实践与书生大模型能力验证

1. 项目背景与核心价值OpenCompass作为当前大模型评测领域的重要工具链,其L2级别的评测实践对于检验书生大模型的实际能力具有重要意义。这次实践不仅是对模型性能的常规测试,更是对模型在复杂场景下表现的系统性验证。在自然语言处理领域,大…

2026/10/24 16:53:27 阅读更多 →
CNN-LSTM-Attention模型在工业时序数据分类中的应用

CNN-LSTM-Attention模型在工业时序数据分类中的应用

1. 项目概述:当CNN遇上LSTM与Attention在时间序列数据分类预测领域,传统单一模型往往难以同时捕捉空间特征和时间依赖。三年前我在处理一组工业传感器数据时,发现单纯使用CNN虽然能提取局部特征,但对长期时序模式识别效果欠佳&…

2026/10/25 19:53:56 阅读更多 →
Codex 经常执行失败怎么办?从开发环境配置到 ChatGPT Pro 选择

Codex 经常执行失败怎么办?从开发环境配置到 ChatGPT Pro 选择

很多开发者第一次使用 Codex 时,会直接把整个项目交给它处理:“帮我修复这个仓库里的所有错误。”“运行项目并解决启动失败的问题。”“完成这个功能,然后把测试全部跑通。”但实际执行后,经常会出现任务停滞、命令报错、依赖安装…

2026/10/25 11:16:44 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →