volatile详解(任何人都能懂的那种)
volatile
看了好多篇博客终于明白这个关键字到底是干嘛的…让我综合所有的博客写一篇大家都能理解它的博客,要点赞呦!!!
volatile是一个类型修饰符,作用是作为指令关键字,一般都是和const对应,确保本条指令不会被编译器的优化而忽略。
先从一个简单的栗子说起吧
看下面一段代码 (选择题中会考!!!)
int main()
{int i = 10;int a = i;printf("%d", i);//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道__asm{mov dword ptr[ebp - 4], 20h}int b = i;printf("i=%d", b);return 0;
}
然后,在debug(调试)版本模式运行程序,输出结果如下:
i = 10
i = 32
然后在release版本模式运行下,输出结果如下:
i = 10
i = 10
输出结果表明一个问题,在release模式下,编译器对代码进行了优化,具体优化结果如下:
由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错
下面,我们把i的声明加上关键字volatile,看看有什么变化没
int main()
{volatile int i = 10;int a = i;printf("%d", i);//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道__asm{mov dword ptr[ebp - 4], 20h}int b = i;printf("i=%d", b);return 0;
}
分别在debug和release版本运行结果都是如下:
i = 10
i = 32
这说明volatile发挥了它的作用。
这时,我们在配合一个例子再次深入理解一下
发薪资时,会计每次都把员工叫来登记他们的银行卡号;一次会计为了省事,没有即时登记,用了以前登记的银行卡号;刚好一个员工的银行卡丢了,已挂失该银行卡号;从而造成该员工领不到工资
员工 -- 原始变量地址
银行卡号 -- 原始变量在寄存器的备份
volatile应该解释为“直接存取原始内存地址”比较合适,“易变的”这种解释简直有点误导人;
精华!!!!(一定要看)
- volatile对应的变量可能在你的程序本身不知道的情况下发生改变
- 比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
- 你自己的程序,是无法判定何时这个变量会发生变化
- 还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
- 对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,**而不会利用cache当中的原有数值,**以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。
让我们举几个volatile的例子
1)并行设备的硬件寄存器(如:状态寄存器)
2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3)多线程应用中被几个任务共享的变量
面试小题
1)一个参数既可以是const还可以是volatile吗?解释为什么。
是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2)一个指针可以是volatile 吗?解释为什么。
是的。尽管这并不很常见。一个例子是当一个中断服务子程序修改一个指向一个buffer的指针时。
3)下面的函数被用来计算某个整数的平方,它能实现预期设计目标吗?如果不能,试回答存在什么问题:
int square(volatile int* &ptr)//这里参数应该申明为引用,不然函数体里只会使用副本,外部没法更改
{int a,b;a = *ptr;b = *ptr;return a*b;
}
由于*ptr的值可能在两次取值语句之间发生改变,因此a和b可能是不同的。结果,这段代码可能返回的不是你所期望的平方值!正确的代码如下:
long square(volatile int*ptr)
{int a;a = *ptr;return a*a;
}
volatile详解(任何人都能懂的那种)相关推荐
- MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
1.系统变量 2.自定义变量 3.存储过程 4.函数 5.流程控制结构 1.系统变量 1.1系统变量的分类 系统变量:分为全局变量和会话变量 1.2系统变量的介绍 系统变量由系统提供,不是用户定义,属 ...
- MySQL视图附带例子详解(小白都能懂哦)
1.视图的概念 2.视图的应用场景 3.视图的特点 4.创建视图的格式 5.视图的修改 6.视图的删除 7.视图的查看 8.视图的更新 9.视图和表格的对比 10.视图的优缺点 1.视图的概念 视图是 ...
- MySQL数据操作(DML)详解(小白都能懂欧)
1.插入语句 1.1插入一行 有两种: 1.以小括号的形式 insert into + 表名(列1,列2...) +values(值1,值2...) 这里注意:如果表名后边不加小括号对应内容,那么默认 ...
- C语言:关键字volatile详解!
一.volatile 介绍 参看:volatile详解 参看:C Language Keywords Indicates that a variable can be changed by a bac ...
- Java多线程之volatile详解
Java多线程之volatile详解 目录: 什么是volatile? JMM内存模型之可见性 volatile三大特性之一:保证可见性 volatile三大特性之二:不保证原子性 volatile三 ...
- Java基础:volatile详解
Java基础:volatile详解 1.volatile保证可见性 1.1.什么是JMM模型? 1.2.volatile保证可见性的代码验证 1.2.1.无可见性代码验证 1.2.1.volatile ...
- java内存 海子_Java虚拟机:JVM内存模型和volatile详解
JVM内存模型和volatile详解 Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内 ...
- Java Volatile 详解
Java Volatile 详解 Volatile:是java虚拟机提供的轻量级的同步机制.保证可见性.禁止指令重排序.不保证原子性!!! 学习Volatile之前必须了解JAVA内存模型. Java ...
- 虚拟摄像头之七:《详解 CameraService 都做了什么》之 CameraService 与 cameraclient 通讯
前言 在阅读本篇内容前.你需要首先了解 android 的 Binder IPC 通讯框架基本原理,才好更好理解 CameraServer 与CameraClient 之间通讯原理;此部分描述的是 a ...
最新文章
- 计算机二级理工类报哪个,计算机二级考哪一科目,毕业后找工作会对科目有要求吗?还是说不管什么科目有证就行了?...
- 2014 I/O归来:Google连接一切
- 全面布局大数据平台,银科控股签约神策数据
- Mysql:Sql的执行顺序
- 媒体声音 | 憋了这么久,阿里云数据库再放大招
- 解决多进程模式下引起的“惊群”效应
- html网页设如何置访问密码,利用JS给单页html加上简单访问密码,需要密码才能访问!...
- aws lambda_Express.js和AWS Lambda —无服务器的爱情故事
- (2006, ‘MySQL server has gone away‘) 原因和解决方案
- mysql 部署在私有云_教你在 RHEL 7 中部署私有云网盘
- MATLAB 读取文件及数据
- 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南):签到题A Matrix Equation(高斯消元求线性异或方程组自由元个数)
- 2020最新微信小程序学习资源汇总,包括文档、视频、系列教程、开源项目、框架!
- js实现轮播图背景色随之渐变的效果(小程序版)
- 手机计算机怎么玩24点游戏,计算器上的24点游戏怎么操作
- 详细讲解半加器、全加器、四位全加器,并使用FPGA实现半加器、全加器
- tensorflow object detection api关于csv转换tfrecord格式
- CentOS 7.2 安装Subversion(SVN)
- 《人月神话》(P10)必须有文档
- 多个.xslx和.txt文件合并