C++基础系列【29】volatile关键字

博主介绍:程序喵大人

什么时候使用volatile关键字?

直接看下面代码:

cpp 复制代码
int a = 100;

while (a == 100) { 
    // code
}

这段程序编译时,如果编译器发现程序始终没有企图改变a的值,那它可能就会优化这段代码,变成while(true)的死循环使得程序执行的更快,然而这种优化有时候会变成过度优化,编译器有时候可能没有意识到程序会改变a的值,却做了这种优化导致程序没有产生预期的行为。

这里为了产生预期的行为,需要阻止编译器做这种优化,可以使用volatile关键字修饰。

cpp 复制代码
volatile int a = 100;

volatile关键字和const关键字相对应,const关键字告诉编译器其修饰的变量是只读的,编译器根据只读属性做一些操作,而volatile关键字告诉编译器其修饰的变量是易变的,同理编译器根据易变属性也会做一些操作。它会确保修饰的变量每次都读操作都从内存里读取,每次写操作都将值写到内存里。

volatile关键字就是给编译器做个提示,告诉编译器不要对修饰的变量做过度的优化,提示编译器该变量的值可能会以其它形式被改变。

volatile修饰结构体时,结构体的成员也是 volatile的吗

cpp 复制代码
struct A {
int data;
};
volatile A a;
const A b;

答案是结构体内所有的都是volatile,引用c++标准里的一句话:

[Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object

because the value of the object might be changed by means undetectable by an implementation.

See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same

in C + + as they are in C. ]

这里大体可以理解为一个对象是volatile,那对象里所有的成员也都是volatile。其实constvolatile可以理解为是硬币的两面,我们经常听到看到传说中的CV修饰词就是constvolatile关键字。

volatile可以保证原子性吗

想必大家都知道答案,volatile只保证内存可见性,不能保证操作是原子的,拿i++举例:

cpp 复制代码
volatile int i = 0;
i++; // i = i + 1

i++ 相当于i=i+1,而i=i+1其实可以分解为好几步:

  • 先读取i的值到tmp
  • 增加tmp的值
  • tmp的值写回到i的地址里

volatile只能保证内存可见,可以理解为上述三步中的每一步都是原子的,但是三步合起来却不一定是原子的,因为在多线程中三步中间可能插入一些其它操作改变了预期的行为,所以**volatile不能用在多线程中**,多线程中的原子操作还是需要使用atomic

tips: volatile不能解决多线程安全问题,针对特种内存才需要使用volatile,它和atomic的特点如下:

  • std::atomic用于多线程访问的数据,且不用互斥量,用于并发编程中
  • volatile用于读写操作不可以被优化掉的内存,用于特种内存中

码字不易,欢迎大家点赞关注评论,谢谢!


C++训练营

专为校招、社招3年工作经验的同学打造的1V1 C++训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得大厂offer!

相关推荐
ACP广源盛139246256733 分钟前
GSV6155@ACP# Type-C 视频信号转换芯片:技术架构、工程痛点适配与落地场景分析
大数据·c语言·开发语言·人工智能·分布式·嵌入式硬件·架构
我不是懒洋洋6 分钟前
从零实现一个分布式数据管道:dbt的核心设计
c++
光子物联单片机7 分钟前
STM32传感器模块编程实践(二十一)DIY语音控制小车套件模型
c语言·stm32·单片机·嵌入式硬件·mcu
铁皮饭盒7 分钟前
网页端OCR, 加载6mb大小模型, 又快又准, 百度这次真香
前端·后端
程序员-Benothing10 分钟前
Java集合:List实现类深度对比
java·开发语言·后端·面试·list
酷在前行18 分钟前
【R论文复刻】Nature Communications 冲积图进阶:状态转移、流带排序与多面板排版(保姆级教程)
开发语言·r语言
Darkwanderor28 分钟前
使用管道实现进程间通信 (IPC, Inter-Process Communitation)
linux·c语言·c++
减瓦32 分钟前
用 Git 为本地文件打造一台时光机
开发语言·git·编辑器
云浪34 分钟前
给 AI Agent 加上语音交互:ASR + 流式 TTS 实战
前端·人工智能·后端
乱七八糟的屋子36 分钟前
【C++数值计算】Armadillo超详细入门教程
c++·线性代数·数值计算·科学计算·矩阵运算·armadillo