volatile关键字详解
本文系转载,原文链接:http://www.cnblogs.com/Chase/archive/2010/07/05/1771700.html,如有侵权,请联系我:534624117@qq.com
引子1
猜猜看,下面这段代码有什么问题:
|
1
2
3
4
|
void Delay(UINT32 n){ while(—n);} |
答案:
本来代码完全正常,但是为了优化性能,打开了编译器的优化。但是发现这个函数被编译器优化掉了。为了防止被优化掉,需要给函数的参数加上volatile:
|
1
2
3
4
|
void Delay(volatile UINT32 n){ while(—n);} |
引子2
再猜猜看,这段代码有什么问题:
|
1
2
3
4
|
int square(volatile int *ptr) { return *ptr * *ptr; } |
答案:
由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
|
1
2
3
4
5
6
7
|
int square(volatile int *ptr) { int a,b; a = *ptr; b = *ptr; return a * b; } |
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
|
1
2
3
4
5
6
|
int square(volatile int *ptr) { int a; a = *ptr; return a * a; } |
正文
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
volatile的本意是“易变的”,不过翻译成“直接存取原始内存地址”更为合适。“易变”是因为外在因素引起的,象多线程,中断等,并不是因为用volatile修饰了的变量就是“易变”了,假如没有外因,即使用volatile定义,它也不会变化。
使用该关键字的例子如下:
|
1
|
int volatile nVint;//当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。 |
对于这样的代码:
|
1
2
3
4
|
volatile int i = 10; int a = i;... //其他代码,并未明确告诉编译器,对i进行过操作int b = i; |
volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
一般说来,volatile用在如下的几个地方:
- 中断服务程序中修改的供其它程序检测的变量需要加volatile;
- 多任务环境下各任务间共享的标志应该加volatile;
- 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
volatile关键字详解的更多相关文章
- Java volatile关键字详解
Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...
- Java之先行发生原则与volatile关键字详解
volatile关键字可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争问题的时候一律使用synchro ...
- C/C++中volatile关键字详解 (转)
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...
- C/C++中volatile关键字详解
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...
- Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...
- Java多线程-----volatile关键字详解
volatile原理 Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后, 编译器与运行时都会注意 ...
- jvm运行机制和volatile关键字详解
参考https://www.cnblogs.com/dolphin0520/p/3920373.html JVM启动流程 1.java虚拟机启动的命令是通过java +xxx(类名,这个类中要有mai ...
- Java中Volatile关键字详解 (转自郑州的文武)
java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...
- Java中Volatile关键字详解
一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...
随机推荐
- 2.1 python使用MongoDB 示例代码
import pymongo client = pymongo.MongoClient('localhost', 27017) # MongoDB 客户端 walden = client['walde ...
- 使用 VS Code 来编辑 markdown 文章
一开始我就用 VS Code 来编辑 markdown 文本,只是因为 VS Code 用起来感觉很好,然后我又去寻找其他的能够预览 markdown 的编辑器,看了好多都不是很方便.突然我发现 VS ...
- 查看SQL Server被锁的表以及如何解锁
锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCK ...
- URLDecoder解析url编码
try { strJson = URLDecoder.decode(strJson, "utf-8"); } catch (UnsupportedEncodingException ...
- VS 团队资源管理 强制解锁锁定文件
故事是这样发生的: 以前有台电脑,在团队资源里看程序,可能冥冥中不小心按了个空格,so,文件被锁定 而我却没有发现 如果再给我一个机会,我只想说记得签入 然后,高潮来了 重装电脑 欣喜的装好新机子打开 ...
- mysql-data-dumper
mysql-data-dumper mysql-data-dumper最近几天写的项目. 一开始仅仅想实现一个简单的数据导出工具,方便大家使用,提升团队成员的效率.后来结果想法天马行空,所以进度有点慢 ...
- JQuery中$.ajax()方法参数详解(转载)
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- yuv420p转为emgucv的图像格式Emgu.CV.Image<Bgr, Byte>
GCHandle handle = GCHandle.Alloc(yuvs, GCHandleType.Pinned); Emgu.CV.Image<Bgr, Byte> image = ...
- BootStrap 杂记
1:Bootstrap中的弹出窗口组件Modal 2:让div或者文字居中 在标签的class里加上 text-center .
- Programming with Objective-C ----------Encapsulating Data
Most Properties Are Backed by Instance Variables By default, a readwrite property will be backed by ...