C++ 原子操作完全指南 + 单例模式实战
C 原子操作完全指南 单例模式实战一、std::atomic 基础1.1 基本用法std::atomic保证对变量的读写是不可中断的线程安全无需显式加锁。#includeatomic#includethread#includeiostreamstd::atomicintcounter{0};voidincrement(){for(inti0;i100000;i){counter;// 原子自增线程安全}}intmain(){std::threadt1(increment);std::threadt2(increment);t1.join();t2.join();std::coutcounter\n;// 保证输出 200000}1.2 核心 API操作说明load()原子读store(val)原子写exchange(val)原子交换返回旧值compare_exchange_weak(expected, desired)CAS原子比较并交换fetch_add(val)/fetch_sub(val)原子加减返回旧值/--重载运算符等价于fetch_add(1)std::atomicinta{10};intxa.load();// x 10a.store(20);// a 20intolda.exchange(30);// old 20, a 30intexpected30;booloka.compare_exchange_weak(expected,40);// 如果 a 30则 a 40返回 true// 如果 a ! 30则 expected a 的当前值返回 false二、内存序 (Memory Order)std::atomic默认使用memory_order_seq_cst顺序一致性性能开销最大。可以显式指定更宽松的内存序。2.1 五种内存序宽松程度 seq_cst acquire/release acq_rel relaxed (最强) (最弱性能最好)内存序含义适用场景memory_order_relaxed只保证原子性不保证顺序纯计数器如引用计数memory_order_acquire读操作之后的读写不会被重排到这次读之前获取锁、读取共享数据memory_order_release写操作之前的读写不会被重排到这次写之后释放锁、发布共享数据memory_order_acq_rel同时包含 acquire release读-修改-写操作如 CASmemory_order_seq_cst全局顺序一致性默认简单但最慢2.2 Acquire-Release 同步示例#includeatomic#includethreadstd::atomicintdata{0};std::atomicboolready{false};voidproducer(){data.store(42,std::memory_order_relaxed);// ① 写数据ready.store(true,std::memory_order_release);// ② 发布信号}voidconsumer(){while(!ready.load(std::memory_order_acquire))// ③ 等待信号;// ④ 保证能看到 ① 的写入std::coutdata.load(std::memory_order_relaxed)\n;// 一定输出 42}intmain(){std::threadt1(producer);std::threadt2(consumer);t1.join();t2.join();}关键release写和acquire读配对形成一个同步点。保证在release之前的所有写操作对acquire之后的读操作可见。三、自旋锁实现CAS 实战#includeatomic#includethreadclassSpinLock{std::atomic_flag flagATOMIC_FLAG_INIT;public:voidlock(){// test_and_set: 原子地设置 flag 为 true返回旧值while(flag.test_and_set(std::memory_order_acquire)){// 自旋等待}}voidunlock(){flag.clear(std::memory_order_release);}};SpinLock spinlock;intshared0;voidwork(){for(inti0;i10000;i){spinlock.lock();shared;// 临界区spinlock.unlock();}}C20 起std::atomic_flag的test()方法可以只读不修改。四、无锁队列简单示例templatetypenameTclassLockFreeStack{structNode{T data;Node*next;};std::atomicNode*head{nullptr};public:voidpush(constTvalue){Node*new_nodenewNode{value,nullptr};// CAS 循环如果 head 没变就更新为 new_nodedo{new_node-nexthead.load(std::memory_order_relaxed);}while(!head.compare_exchange_weak(new_node-next,// expectednew_node,// desiredstd::memory_order_release,std::memory_order_relaxed));}boolpop(Tresult){Node*old_headhead.load(std::memory_order_acquire);while(old_head!nullptr){if(head.compare_exchange_weak(old_head,old_head-next,std::memory_order_release,std::memory_order_relaxed)){resultold_head-data;deleteold_head;// 实际工程中需要用 Hazard Pointer 或 RCUreturntrue;}}returnfalse;}};五、注意事项坑说明不是万能锁原子操作适合简单计数/标志复杂逻辑还是要用mutexABA 问题CAS 中值从 A→B→ACAS 认为没变。解决带标签的指针Tagged Pointer伪共享 (False Sharing)两个原子变量在同一缓存行不同 CPU 核频繁修改会互相拖累。解决alignas(64)只能用于平凡可复制类型std::atomicstd::string不行std::atomicint可以compare_exchange_weak vs strongweak可能伪失败被中断适合循环strong保证真失败才返回 false适合单次检查性能对比std::atomicinta{0};// 最慢但最直观a.store(1);// 等价于 memory_order_seq_cst// 快 2~10 倍x86 上差距小ARM 上差距大a.store(1,std::memory_order_relaxed);经验法则如果不需要跨线程的happens-before关系用relaxed如果需要发布-订阅模式用release/acquire配对如果搞不清用默认的seq_cstcorrectness first六、单例模式 原子操作实战6.1 基于 atomic 的双检查锁DCLPC11 之前 DCLP 有指令重排序问题C11 引入std::atomic后可以安全实现。#includeatomic#includemutex#includeiostreamclassSingleton{public:staticSingleton*getInstance(){Singleton*tmpinstance.load(std::memory_order_acquire);if(tmpnullptr){// 第一次检查无锁std::lock_guardstd::mutexlock(mutex);// 加锁tmpinstance.load(std::memory_order_relaxed);if(tmpnullptr){// 第二次检查有锁tmpnewSingleton();// release: 保证 new Singleton() 的构造完成// 对其它线程的 acquire 可见instance.store(tmp,std::memory_order_release);}}returntmp;}voiddoSomething(){std::coutSingleton::doSomething()\n;}private:Singleton()default;~Singleton()default;Singleton(constSingleton)delete;Singletonoperator(constSingleton)delete;staticstd::atomicSingleton*instance;staticstd::mutex mutex;};std::atomicSingleton*Singleton::instance{nullptr};std::mutex Singleton::mutex;// 使用intmain(){Singleton*sSingleton::getInstance();s-doSomething();}关键点instance.load(std::memory_order_acquire)确保看到其他线程release的完整构造对象instance.store(tmp, std::memory_order_release)确保构造完成后再发布指针双重检查第一次无锁快速路径第二次有锁保证唯一性6.2 基于 atomic_flag 的无锁单例更轻量如果单例构造很快可以用atomic_flag实现一个轻量级自旋锁版本的单例。#includeatomic#includethread#includeiostream#includevectorclassSpinLockSingleton{public:staticSpinLockSingleton*getInstance(){// 快速路径已初始化直接返回SpinLockSingleton*tmpinstance.load(std::memory_order_acquire);if(tmp!nullptr){returntmp;}// 慢速路径自旋等待初始化完成while(flag.test_and_set(std::memory_order_acquire)){// 自旋中检查是否其他线程已经初始化完成tmpinstance.load(std::memory_order_relaxed);if(tmp!nullptr){flag.clear(std::memory_order_release);// 释放锁虽然没拿到returntmp;}}// 拿到锁执行初始化tmpinstance.load(std::memory_order_relaxed);if(tmpnullptr){tmpnewSpinLockSingleton();instance.store(tmp,std::memory_order_release);std::coutSingleton initialized by thread\n;}flag.clear(std::memory_order_release);returntmp;}intgetValue()const{returnvalue;}private:SpinLockSingleton():value(42){}~SpinLockSingleton()default;staticstd::atomicSpinLockSingleton*instance;staticstd::atomic_flag flag;intvalue;};std::atomicSpinLockSingleton*SpinLockSingleton::instance{nullptr};std::atomic_flag SpinLockSingleton::flagATOMIC_FLAG_INIT;// 多线程测试intmain(){std::vectorstd::threadthreads;for(inti0;i10;i){threads.emplace_back([](){auto*sSpinLockSingleton::getInstance();std::coutValue: s-getValue()\n;});}for(autot:threads)t.join();}6.3 基于 call_once 的现代写法推荐生产环境虽然这不是纯 atomic 实现但它是最安全的现代 C 单例写法底层由标准库保证原子性。#includemutex#includeatomic#includeiostreamclassModernSingleton{public:staticModernSingletongetInstance(){std::call_once(initFlag,ModernSingleton::init);return*instance;}voiddoSomething(){std::coutModernSingleton::doSomething(), valuevalue\n;}private:ModernSingleton():value(100){}~ModernSingleton()default;staticvoidinit(){instancenewModernSingleton();}staticstd::once_flag initFlag;staticModernSingleton*instance;intvalue;};std::once_flag ModernSingleton::initFlag;ModernSingleton*ModernSingleton::instancenullptr;6.4 基于 static local variable 的最简写法C11 起线程安全classSimpleSingleton{public:staticSimpleSingletongetInstance(){staticSimpleSingleton instance;// C11 起保证线程安全初始化returninstance;}voiddoSomething(){}private:SimpleSingleton()default;~SimpleSingleton()default;SimpleSingleton(constSimpleSingleton)delete;SimpleSingletonoperator(constSimpleSingleton)delete;};C11 标准规定函数内的static局部变量初始化是线程安全的由编译器插入原子操作保证。这是最推荐的写法。七、单例模式选择指南实现方式线程安全性能复杂度推荐场景static local✅ C11 标准保证最优无锁最低首选绝大多数场景std::call_once✅优低需要延迟初始化且构造可能抛异常atomic DCLP✅优中学习原子操作原理、需要手动控制内存序atomic_flag 自旋锁✅良中构造极快、不想用 mutexmutex✅一般低简单场景不追求极致性能八、一句话总结std::atomic提供无锁的原子操作通过内存序控制可见性和重排序。relaxed最快但最弱release/acquire是性能与正确性的平衡点seq_cst最安全但最慢。CAS 是实现无锁数据结构的基石要小心 ABA 和伪共享。单例模式优先用 C11 的static local变量学习原子操作原理时可以用atomic DCLP实现。声明本文档由 AIMoonshot AI / Kimi辅助生成内容仅供参考请根据实际情况核实和使用。 仅供学习使用

相关新闻

深度剖析 AI 在电商行业的落地应用、瓶颈与发展机遇

深度剖析 AI 在电商行业的落地应用、瓶颈与发展机遇

随着生成式AI与AI Agent技术快速普及,人工智能已从概念工具,升级为电商数字化转型的核心生产力。AI全面覆盖电商内容、营销、服务、供应链全链路,大幅解决传统电商高成本、低产能、粗放运营的痛点。本文结合TKONE电商AI落地实战,精…

2026/7/29 21:29:07 阅读更多 →
基于SpringBoot+Vue的家用车辆美容养护管理系统设计与实现开题报告

基于SpringBoot+Vue的家用车辆美容养护管理系统设计与实现开题报告

、课题研究背景与意义 (一)研究背景 随着国民经济水平的持续提升与汽车工业的快速发展,家用汽车普及率逐年攀升,汽车已成为大众日常出行的核心交通工具。随着家用车辆保有量的不断增长,车主对车辆定期美容、保养、维修…

2026/7/29 21:28:07 阅读更多 →
Source Han Serif CN:如何用开源方案解决中文字体商用困境?

Source Han Serif CN:如何用开源方案解决中文字体商用困境?

Source Han Serif CN:如何用开源方案解决中文字体商用困境? 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 在中文设计领域,商用字体授权费用动辄数…

2026/7/29 21:28:07 阅读更多 →

最新新闻

同一笔双均线策略,我手写了40分钟,AI用一句话生成——回测结果差多少?

同一笔双均线策略,我手写了40分钟,AI用一句话生成——回测结果差多少?

QuantDingerhttps://github.com/OpenByteInc/QuantDinger QuantDinger是一个开源的AI交易平台——10.1K星,Python编写,本地自托管,支持加密货币、IBKR美股和MT5外汇。它的核心能力就一个:你用中文描述交易想法,AI自动…

2026/7/29 21:39:11 阅读更多 →
2026年国内龙虾软件推荐:五款AI智能体实测横评与选型指南

2026年国内龙虾软件推荐:五款AI智能体实测横评与选型指南

什么是龙虾软件龙虾软件是国内开发者社区对OpenClaw生态及其衍生AI智能体产品的俗称。这类软件的核心特征在于:它们不只是被动回答问题的聊天工具,而是能够主动操控电脑、调用应用、执行复杂任务的AI执行框架。与传统的问答式AI助手不同,龙虾…

2026/7/29 21:39:11 阅读更多 →
达梦sql_monitor信息的进一步加工

达梦sql_monitor信息的进一步加工

当达梦sql monitor输出结果太多时(800行),不方便查看可以考虑大力加工一下,思路是创建一个表,将结果输入进去,然后方便用sql进行排序和分析。 et知道某个步骤最耗时,但是不知道对象。大力加工&a…

2026/7/29 21:39:11 阅读更多 →
零基础打造专属AI画师:Kohya_SS图形化训练工具完全指南

零基础打造专属AI画师:Kohya_SS图形化训练工具完全指南

零基础打造专属AI画师:Kohya_SS图形化训练工具完全指南 【免费下载链接】kohya_ss 项目地址: https://gitcode.com/GitHub_Trending/ko/kohya_ss 你是否曾梦想拥有一个能理解你独特艺术风格的AI助手?现在,这个梦想通过Kohya_SS变得触…

2026/7/29 21:39:11 阅读更多 →
GetQzonehistory:三步轻松备份QQ空间完整历史说说的终极解决方案

GetQzonehistory:三步轻松备份QQ空间完整历史说说的终极解决方案

GetQzonehistory:三步轻松备份QQ空间完整历史说说的终极解决方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字记忆日益珍贵的今天,QQ空间承载着我们青春…

2026/7/29 21:39:11 阅读更多 →
2026年开学返校行李箱怎么选?5款实测对比,学生党看这一篇就够了

2026年开学返校行李箱怎么选?5款实测对比,学生党看这一篇就够了

每年8月中下旬,后台私信里问得最多的问题就是:开学返校行李箱到底怎么选?直接给结论:24寸是绝大多数住校生的黄金尺寸,材质优先认准ABSPC复合或纯PC,轮子必须选双排TPE静音万向轮,预算控制在300…

2026/7/29 21:38:11 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻