c++ std::atomic如何保证原子性 c++ CAS操作原理【底层】
发布时间 - 2026-01-01 00:00:00 点击率:次std::atomic的原子性由编译器生成特定CPU指令(如x86的lock、ARM的ldxr/stxr)与硬件共同实现,CAS是核心原语;compare_exchange_weak允许伪失败,compare_exchange_strong无伪失败;内存序控制可见性而非原子性。
std::atomic 的原子性不是靠 C++ 语言本身“保证”的,而是通过编译器生成特定的底层指令(如 x86 的 lock 前缀指令、ARM 的 ldxr/stxr 等)+ CPU 硬件支持共同实现的。CAS(Compare-And-Swap)是其中最核心的原语,它的原子性直接由 CPU 提供。
CPU 级别的原子操作支持
现代 CPU 在硬件层面提供了对单条内存访问指令的原子保障,但仅限于满足对齐、大小等条件的简单读写(如 4 字节对齐的 int)。而像“读-改-写”这类复合操作(例如 i++),天然不是原子的——中间可能被中断或并发修改。为此,CPU 提供了专门的原子指令:
- x86/x64:使用
lock cmpxchg指令实现 CAS;lock前缀会锁定总线或缓存行(取决于架构和操作数大小),阻止其他核心/线程在同一时间修改同一缓存行。 - ARM64:使用
ldxr(load-exclusive) +stxr(store-exclusive)配对。CPU 会标记某地址为“独占监视”,后续stxr成功当且仅当该地址未被其他核心修改过——失败则需重试。 - RISC-V:类似 ARM,用
lr.w/sc.w(load-reserved / store-conditional)机制。
std::atomic::compare_exchange_weak/strong 的底层行为
这两个函数最终映射到上述 CPU 指令。区别在于:
-
compare_exchange_weak允许“伪失败”(spurious failure):即使预期值匹配,也可能因底层机制(如 ARM 的独占监视被意外清除)返回 false。适合循环重试场景,性能略高。 -
compare_exchange_strong保证:只要预期值匹配,就一定成功(无伪失败)。但某些平台(如早期 ARM)需额外检查+重试模拟,开销
稍大。
典型用法是循环尝试:
int expected = val.load();while (!val.compare_exchange_weak(expected, desired)) {
// expected 已被更新为当前实际值
}
内存序(memory order)不是原子性,但影响可见性
原子性只解决“执行不中断”,不解决“结果何时对其他线程可见”。std::memory_order 控制编译器重排和 CPU 指令重排,以及缓存同步时机:
-
memory_order_relaxed:只保证该操作自身原子,不约束前后内存访问顺序,也不触发 cache coherency 同步(最快,适合计数器等无需同步语义的场景)。 -
memory_order_acquire(读)/memory_order_release(写):构成“获取-释放”同步,保证本线程中该操作前后的内存访问不会跨过它重排,并在多核间建立 happens-before 关系。 -
memory_order_seq_cst(默认):最强语义,所有线程看到的操作顺序一致,相当于全局顺序锁,性能开销最大。
编译器与运行时的协作
std::atomic 对象在编译期会被标记为不可分割访问(禁止拆解为多个 mov 指令),并根据模板参数类型选择对应宽度的原子指令(如 atomic → 32 位指令)。对于不支持原生原子操作的类型(如过大结构体),std::atomic 会退化为内部加锁(如 mutex),此时原子性由互斥量保证,而非硬件指令——但这已不属于“无锁原子操作”范畴。
# app
# 字节
# ai
# c++
# 区别
# 无锁
# red
# 架构
# while
# 结构体
# int
# 循环
# Conditional
# 线程
# 并发
# 对象
# 重试
# 多核
# 而非
# 也不
# 见性
# 多个
# 已被
# 并在
# 这两个
# 这类
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Swift中swift中的switch 语句
如何快速选择适合个人网站的云服务器配置?
如何用好域名打造高点击率的自主建站?
如何在香港免费服务器上快速搭建网站?
如何确认建站备案号应放置的具体位置?
EditPlus中的正则表达式实战(5)
如何选择可靠的免备案建站服务器?
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
Laravel如何优化应用性能?(缓存和优化命令)
LinuxShell函数封装方法_脚本复用设计思路【教程】
如何快速配置高效服务器建站软件?
PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑
图册素材网站设计制作软件,图册的导出方式有几种?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
如何安全更换建站之星模板并保留数据?
Android okhttputils现在进度显示实例代码
香港服务器租用每月最低只需15元?
Swift中switch语句区间和元组模式匹配
微信小程序 wx.uploadFile无法上传解决办法
网站制作壁纸教程视频,电脑壁纸网站?
实例解析Array和String方法
高端智能建站公司优选:品牌定制与SEO优化一站式服务
北京企业网站设计制作公司,北京铁路集团官方网站?
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
UC浏览器如何设置启动页 UC浏览器启动页设置方法
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
如何用PHP快速搭建高效网站?分步指南
如何在万网自助建站平台快速创建网站?
如何在香港服务器上快速搭建免备案网站?
如何快速重置建站主机并恢复默认配置?
在线制作视频网站免费,都有哪些好的动漫网站?
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
使用豆包 AI 辅助进行简单网页 HTML 结构设计
如何快速生成橙子建站落地页链接?


稍大。