volatile变量禁用编译器优化但不保证原子性与线程安全,适用于硬件寄存器、信号处理等外部修改场景,多线程应使用std::atomic;可与const共用,表示只读但外部可变。
声明为 volatile 的变量,告诉编译器:这个值可能在当前代码控制之外被改变(比如硬件寄存器、多线程共享变量、信号处理函数中修改的全局变量),因此每次读写都必须真实发生,不能被缓存到寄存器、不能被合并、也不能被删除。
但它完全不提供线程安全:volatile int flag = 0; 在多线程中做 flag = 1; 或 while(flag == 0); 仍可能因缺少内存屏障或原子操作而失效。C++11 起应优先用 std::atomic 替代。
典型使用场景有限,常见于嵌入式或系统编程:
volatile uint32_t* const ctrl_reg = reinterpret_cast(0x40001000);
sig_atomic_t 类型更稳妥)普通多线程标志位、计数器、状态变量——volatile 无法阻止重排序,也无法保证读写顺序,不要用它替代同步原语。
可以,且常见:const volatile uint32_t* reg_ptr; 表示指针指向的内容既不能被当前代码修改(const),又可能被外部修改(volatile)。这种组合在只读硬件寄存器中很典型。
注意:volatile 不影响对象的可变性语义,它只约束编译器生成的访问方式;const 约束的是本代码能否写入。二者作用域不同,不冲突。
写一个简单函数对比汇编输出:
int global_var = 0;
void test_normal() {
global_var = 1;
global_var = 2;
}
void test_volatile() {
volatile int v = 0;
v = 1;
v = 2;
}用 g++ -S -O2 test.cpp 查看汇编:test_normal 中对 global_var 的两次赋值很可能被合并或优化掉;而 test_volatile 中的两次 v = ... 会生成两条独立的内存写指令(如 mov DWORD PTR [rbp-4], 1 和 mov DWORD PTR [rbp-4], 2)。
这是验证 volatile 是否起作
用最直接的方式。但要注意:它只反映编译器行为,不涉及 CPU 乱序或缓存一致性。
真正跨线程通信时,volatile 很容易给人“已经同步”的错觉,而实际执行结果不可靠——这点最容易被忽略。
# word
# c++
# 作用域
# while
# const
# 全局变量
# int
# volatile
# 循环
# 指针
# 线程
# 多线程
# 对象
# 异步
# 两次
# 信号处理
# 但不
# 它只
# 的是
# 这是
# 适用于
# 很容易
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Windows 11怎么更改锁屏超时时间_Windows 11电源选项中设置屏幕关闭时间
如何解决同一段404代码在不同主机上表现不一致的问题
Win11如何设置系统语言_Win11系统语言切换教程【攻略】
Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】
Win11怎么设置组合键快捷方式_Windows11自定义快捷键操作
短链接怎么自定义还原php_修改解码规则适配需求【汇总】
Python模块的__name__属性如何由导入方式决定?
如何使用正则表达式批量替换重复的 *- 模式为固定字符串
Win11用户账户控制怎么关_Win11关闭UAC弹窗提示【设置】
Mac如何创建和管理多个桌面空间_Mac高效多任务处理【技巧】
Windows10怎么查看系统激活状态_Windows10激活状态查看方法【教程】
Win11怎么设置任务栏对齐方式_Windows11个性化任务栏行为
MAC如何修改默认应用程序_MAC文件后缀关联设置与打开方式更改【教程】
如何使用Golang实现负载均衡_分发请求到多个服务节点
MAC怎么解压RAR格式文件_MAC第三方解压工具安装与压缩包管理【教程】
Win11如何关闭游戏模式 Win11禁用Xbox Game Bar录制【优化】
如何自定义Windows终端的默认配置文件?(PowerShell/CMD)
如何高效删除 NumPy 二维数组中所有元素相同的列
Mac版Final Cut Pro入门_Mac视频剪辑基础操作【教程】
本地php环境打开php文件直接下载_浏览器解析php为下载的修复方法【解答】
php怎么下载安装后无法解析php文件_服务器配置检查【解答】
Win10电脑C盘红了怎么清理_Windows10系统盘深度瘦身指南
win11 OneDrive怎么彻底关闭 Win11禁用并卸载OneDrive教程【分享】
PHP主流架构怎么处理表单验证_规则与自定义【技巧】
C++如何获取CPU核心数?(std::thread::hardware_concurrency)
Win11怎么退出微软账户_切换Win11为本地账户登录方法【详解】
Win11怎么开启剪贴板历史记录_Windows11 Win+V键使用技巧
Python日志系统设计与实现_高可观测性架构实战
php怎么下载安装后设置默认字符集_utf8配置步骤【详解】
Win11怎么开启HDR模式_Windows 11高动态范围显示设置指南【详解】
Windows10如何彻底关闭自动更新_Win10服务与组策略双重禁用
Win11文件夹预览图不显示怎么办_Win11缩略图缓存重建修复【教程】
php怎么操作Redis_Redis扩展连接与基本命令使用方法【方法】
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
mac怎么查看wifi密码_MAC查看已连接WiFi密码方法【技巧】
Win11怎么设置桌面图标间距_Windows11注册表IconSpacing修改
PHP主流架构如何做单元测试_工具与流程【详解】
Mac如何彻底清理浏览器缓存?(Safari与Chrome)
如何提升Golang程序I/O性能_Golang I/O密集型程序优化示例
如何使用Golang构建简易投票统计功能_Golang投票数据汇总与展示示例
如何使用Golang捕获测试日志_Golang testing日志记录方法
Win11怎么关闭触摸屏_禁用Win11笔记本触摸屏功能设置【教程】
Win11怎么关闭SmartScreen_禁用Windows Defender筛选器教程【步骤】
php下载安装包怎么选_threadsafe与nts版本差异【解答】
Windows10系统怎么查看系统版本_Win10运行winver命令查询
LINUX如何删除用户和用户组_Linux userdel和groupdel命令用法【系统管理】
Win11怎么更改电脑名称_Windows 11修改计算机名操作指南【步骤】
Win11如何设置文件权限 Win11 NTFS文件夹所有权与安全设置【高级】
Windows 10怎么把任务栏放在屏幕上方_Windows 10解锁任务栏并拖动位置
php本地部署后session无法保存_session存储路径与权限设置技巧【技巧】
2026-01-05
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。