分享牛人就是的volatilekeyword

volatile作用

一个定义为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的本意是“易变的”

因为訪问寄存器的速度要快过RAM。所以编译器一般都会作降低存取外部RAM的优化。

比方:

static int i=0;

int main(void)

{

...

while (1)

{

if (i) dosomething();

}

}

void ISR_2(void)

{

i=1;

}

程序的本意是希望ISR_2中断产生时。在main其中调用dosomething函数,可是。因为编译器推断在main函数里面没有改动过i,因此

可能仅仅运行一次对从i到某寄存器的读操作,然后每次if推断都仅仅使用这个寄存器里面的“i副本”,导致dosomething永远也不会被

调用。假设将将变量加上volatile修饰。则编译器保证对此变量的读写操作都不会被优化(肯定运行)。此例中i也应该如此说明。

一般说来,volatile用在例如以下的几个地方:

1、中断服务程序中改动的供其他程序检測的变量须要加volatile

2、多任务环境下各任务间共享的标志应该加volatile

3、存储器映射的硬件寄存器通常也要加volatile说明。由于每次对它的读写都可能由不允许义;

另外,以上这几种情况常常还要同一时候考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中能够通过关中断来实

现,2中能够禁止任务调度。3中则仅仅能依靠硬件的良好设计了。

volatile 的含义

volatile总是与优化有关。编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在哪里使用、在哪里失效。分析结果能够用于常量合并,常量传播等优化,进一步能够死代码消除。但有时这些优化不是程序所须要的,这时能够用volatilekeyword禁止做这些优化,volatile的字面含义是易变的,它有以下的作用:

1 不会在两个***作之间把volatile变量缓存在寄存器中。在多任务、中断、甚至setjmp环境下。变量可能被其它的程序改变。编译器自己无法知道,volatile就是告诉编译器这样的情况。

2 不做常量合并、常量传播等优化,所以像以下的代码:

volatile int i = 1;

if (i > 0) ...

if的条件不会当作无条件真。

3 对volatile变量的读写不会被优化掉。假设你对一个变量赋值但后面没用到。编译器经常能够省略那个赋值***作,然而对Memory Mapped IO的处理是不能这样优化的。

前面有人说volatile能够保证对内存操作的原子性。这样的说法不大准确,其一,x86须要LOCK前缀才干在SMP下保证原子性。其二,RISC根本不能对内存直接运算,要保证原子性得用别的方法,如atomic_inc。

对于jiffies,它已经声明为volatile变量。我觉得直接用jiffies++就能够了,不是必需用那种复杂的形式。由于那样也不能保证原子性。

================================================================================

关键在于两个地方:

1. 编译器的优化  (请高手帮我看看以下的理解)

在本次线程内, 当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后,再取变量值时。就直接从寄存器中取值;

当变量值在本线程里改变时,会同一时候把变量的新值copy到该寄存器中。以便保持一致

当变量在因别的线程等而改变了值,该寄存器的值不会对应改变。从而造成应用程序读取的值和实际的变量值不一致

当该寄存器在因别的线程等而改变了值,原变量的值不会改变,从而造成应用程序读取的值和实际的变量值不一致

举一个不太准确的样例:

发薪资时,会计每次都把员工叫来登记他们的银行卡号;一次会计为了省事,没有即时登记,用了曾经登记的银行卡号。刚好一个员工的银行卡丢了。已挂失该银行卡号;从而造成该员工领不到工资

员工 -- 原始变量地址

银行卡号 -- 原始变量在寄存器的备份

2. 在什么情况下会出现(如1楼所说)

1). 并行设备的硬件寄存器(如:状态寄存器)

2). 一个中断服务子程序中会訪问到的非自己主动变量(Non-automatic variables)

3). 多线程应用中被几个任务共享的变量

补充: volatile应该解释为“直接存取原始内存地址”比較合适,“易变的”这样的解释简直有点误导人。

“易变”是由于外在因素引起的,象多线程,中断等,并非由于用volatile修饰了的变量就是“易变”了,假如没有外因。即使用volatile定义,它也不会变化;

而用volatile定义之后,事实上这个变量就不会因外因而变化了,能够放心使用了;大家看看前面那种解释(易变的)是不是在误导人

另外补充volatile在DSP中的理解:

该单词的意思是可变的,易变的。在DSP中,一些寄存器的值的变化有两种情况:(1)硬件上导致的变化。比如中断、ADC等;(2)软件上的变化,比如对某个变量赋值等。

当增加了keywordvolatile。则表示该变量的值可因上述两种情况而发生变化;即,对软件来说,硬件上变化的值是不可预知的,增加了该keyword,提示编译器每次读取该变量时。都要直接读取该变量地址中的寄存器。保证了数据的正确性。

时间: 2025-01-08 04:22:20

分享牛人就是的volatilekeyword的相关文章

IOS 分享 牛人 Demo

ios6.0系统自带分享到新浪微博 (2013-03-21 23:02:58) 转载▼ 标签: slcomposeviewcontrol slservicetypesinawei ios6.0分享到新浪微博   在6.0时候,苹果整合新浪微博,真的很强大,不用在让开发者挨个挨个去整了,苹果要是能整合更多主流社交平台就更好了.   首先还是导入系统自带库文件social.Framework,在需要的控制器里导入#import ,由于是6.0之后的特性,所以为了兼顾低版本,需要进行版本判断使用不同分

[干货分享]转:一位IT牛人的十年经验之谈

1.分享第一条经验:“学历代表过去.能力代表现在.学习力代表未来.”         其实这是一个来自国外教育领域的一个研究结果.相信工作过几年.十几年的朋友对这个道理有些体会吧.但我相信这一点也很重要:“重要的道理明白太晚将抱憾终生!”所以放在每一条,让刚刚毕业的朋友们早点看到哈!         2.一定要确定自己的发展方向,并为此目的制定可行的计划.         不要说什么,“我刚毕业,还不知道将来可能做什么?”,“跟着感觉走,先做做看”.因为,这样的观点会通过 你的潜意识去暗示你的行

【转】牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会写生产者.消费者问题,完全消化理解) 5. 线程的实现方式. (也就是用户线程与内核线程的区别) 6. 用户态和核心态的区别. 7. 用户栈和内核栈的区别. 8. 内存池.进程池.线程池.(c++程序员必须掌握) 9. 死锁的概念,导致死锁的原因. 10. 导致死锁的四个必要条件. 11. 处理死锁

[转载]那些C++牛人的博客

现整理收集C++世界里那些“牛人”的个人博客.凡三类:一是令人高山仰止的大牛,对C++语言本身产生过深远的影响的人:二是C++运用炉火纯青的高手,有原创性的技术干货:三是中文世界里的C++牛人. C++大牛的博客 Bjarne Stroustrup的博客: Bjarne Stroustrup’s Homepage Bjarne Stroustrup,不认识的可以去面壁了,没有他,就没有我们现在的饭碗.Bjarne Stroustrup是丹麦人,目前任教于TAMU.他的Homepage和他的书籍T

paper 61:计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接

转载出处:blog.csdn.net/carson2005 以下链接是本人整理的关于计算机视觉(ComputerVision, CV)相关领域的网站链接,其中有CV牛人的主页,CV研究小组的主页,CV领域的paper,代码,CV领域的最新动态,国内的应用情况等等.打算从事这个行业或者刚入门的朋友可以多关注这些网站,多了解一些CV的具体应用.搞研究的朋友也可以从中了解到很多牛人的研究动态.招生情况等.总之,我认为,知识只有分享才能产生更大的价值,真诚希望下面的链接能对朋友们有所帮助.(1)goog

IT牛人博客

IT牛人博客,参见:http://blog.csdn.net/freebird_lb/article/details/8210276 团队技术博客 淘宝UED淘宝用户体验团队 淘宝核心系统淘宝核心系统团队博客 阿里巴巴数据库团队专注数据库管理开发运维 淘宝通用产品专注JAVA技术 淘宝QA致力于做测试的行业标准 淘宝搜索技术关注技术 关注搜索 量子恒道专注大数据统计 百度搜索研发关注搜索相关技术 EMC中国研究院关注于云计算和大数据 贰号楼肆层阿里巴巴平台技术部 阿里数据平台阿里巴巴数据平台 百

Java开发牛人十大必备网站

以下是我收集的Java开发牛人必备的网站.这些网站可以提供信息,以及一些很棒的讲座, 还能解答一般问题.面试问题等.质量是衡量一个网站的关键因素,我个人认为这些网站质量都很好.接下来,我会跟大家分享我是如何使用这些网站学习和娱乐的.或许你会认为有些网站适合任何水平的开发者,但是我认为:对于Java开发牛人来说,网站的好坏取决于如何使用它们. 1.Stackoverflow Stackoverflow.com 可能是编程界中最流行的网站了,该网站有成千上万个好问题和答案.学习API或者编程语言,通

计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接

提示:本文为笔者原创,转载请注明出处:blog.csdn.net/carson2005 以下链接是本人整理的关于计算机视觉(ComputerVision, CV)相关领域的网站链接,其中有CV牛人的主页,CV研究小组的主页,CV领域的paper,代码,CV领域的最新动态,国内的应用情况等等.打算从事这个行业或者刚入门的朋友可以多关注这些网站,多了解一些CV的具体应用.搞研究的朋友也可以从中了解到很多牛人的研究动态.招生情况等.总之,我认为,知识只有分享才能产生更大的价值,真诚希望下面的链接能对朋

计算机视觉牛人博客和代码汇总

每个做过或者正在做研究工作的人都会关注一些自己认为有价值的.活跃的研究组和个人的主页,关注他们的主页有时候比盲目的去搜索一些论文有用多了,大牛的或者活跃的研究者主页往往提供了他们的最新研究线索,顺便还可八一下各位大牛的经历,对于我这样的小菜鸟来说最最实惠的是有时可以找到源码,很多时候光看论文是理不清思路的. 1 牛人Homepages(随意排序,不分先后): 1.USC Computer Vision Group:南加大,多目标跟踪/检测等: 2.ETHZ Computer Vision Lab