何时该用volatile?
来源:互联网 发布:淘宝折叠桌子 编辑:程序博客网 时间:2024/03/28 23:43
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
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 关键字告诉编译器不要持有变量的临时性拷贝。一般用在多线程程序中,以避免在其中一个线程操作该变量时,将其拷贝入寄存器。请看以下情形:
A线程将变量复制入寄存器,然后进入循环,反复检测寄存器的值是否满足一定条件(它期待B线程改变变量的值。在此种情况下,当B线程改变了变量的值时,已改变的值对其在寄存器的值没有影响。所以A线程进入死循环。
volatile 就是在此种情况下使用。
- 何时该用volatile?
- 何时该用CHAR,何时该用varchar2?
- Problem 63 何时该用glDrawTexiOES?
- 浅谈__declspec(selectany)该何时用
- 何时该用DOM脚本设置样式
- 浅谈__declspec(selectany)该何时用
- c++中何时该用“引用传递”,何时该用“值传递”
- [原创翻译]在何时该用什么方式编译WinCE
- 在何时该用什么方式编译WinCE
- 在何时该用什么方式编译WinCE
- 在何时该用什么方式编译WinCE
- 何时该引用传递 , 何时该指…
- 何时该使用margin、padding
- Java何时该使用覆盖?
- [原创翻译]在何时该用什么方式编译WinCE(By wwfiney@ARMCE)
- [原创翻译][新手必看]在何时该用什么方式编译WinCE
- 在何时该用什么方式编译WinCE(By wwfiney@ARMCE)
- 项目经理知道该何时全身而退
- 用户体验中沟通的技巧
- 中亚天然气管道项目锡尔河第一条主管线穿越成功
- 3d数学基础读书笔记-坐标系篇
- 二十几岁的女孩
- 网站更换系统了,怎么让搜索引擎尽快收录呢
- 何时该用volatile?
- asp横排显示数据
- ubuntu通过下载后更新firefox
- Loadrunner 8.1中文版-参数化
- 请问,windows的计划任务中的job可以一次性copy到另一台windows上吗?
- 庆祝。~
- 忘了Mysql Root密码 - 重置Mysql Root密码
- datastage server job之java调用datastage job
- 郑重推荐 :[你必须知道的.NET]目录导航 作者:Anytao 出处:博客园