volatie关键字

在嵌入式系统中这个关键字用的比较多,主要的用途是避免的编译器的优化。提醒它所声明的这个变量随时可能改变,所以,编译后的程序每次需要存储或读取这变量的时候,都会直接从变量地址中读取数据。

比如一个信号量是某个 io口的高低电平,由于访问寄存器的速度要快于RAM,所以编译器一般都会作减少存取外部RAM的优化。

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

1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 
2、多任务环境下各任务间共享的标志应该加volatile; 
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

这里以多线程程序为例

DWORD __stdcall threadFunc(LPVOID signal) 

int* intSignal=reinterpret_cast

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; 

讲讲我的理解: (欢迎打板子…~~!) 关键在于两个地方: 
1. 编译器的优化 (请高手帮我看看下面的理解) 在本次线程内, 当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后,再取变量值时,就直接从寄存器中取值; 当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致 当变量在因别的线程等而改变了值,该寄存器的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致 当该寄存器在因别的线程等而改变了值,原变量的值不会改变,从而造成应用程序读取的值和实际的变量值不一致 举一个不太准确的例子: 发薪资时,会计每次都把员工叫来登记他们的银行卡号;一次会计为了省事,没有即时登记,用了以前登记的银行卡号;刚好一个员工的银行卡丢了,已挂失该银行卡号;从而造成该员工领不到工资 员工 -- 原始变量地址 银行卡号 -- 原始变量在寄存器的备份 2. 在什么情况下会出现

时间: 2024-08-04 17:05:57

volatie关键字的相关文章

【CDMI-PROJECT】Day-1

1. Java中单元测试中:@BeforeClass,@Before,@Test,@After,@AfterClass中的问题详解 其中:@BeforeClass,@AfterClass是Junit4中新添加进去的 如果Run as ->Junit Test,运行含有@Test注释的方法是,那么所有注解方法都将被执行,所含的执行顺序是: @BeforeClass ,@Before,@Test,@After,@AfterClass 在JUnit4中,如果测试类继承了TestCase类,那么所有的A

多线程-3(同步)

SemaphoreSlim类 代码: static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(4);//只允许4个并行执行的线程 public static void AccessDataBase(string name,int seconde) { Console.WriteLine("{0} 等待访问数据库", name); semaphoreSlim.Wait(); Console.WriteLine("{0} 授予

“volatile”这个关键字

我们经常使用"volatile"这个关键字,它是什么意思? 解析:volatile问题.当一个对象的值可能会在编译器的控制或监测之外被改变时,例如一个被系统时钟更新的变量,那么该对象应该声明成volatile.因此编译器执行的某些例行优化行为不能应用在已指定为volatile的对象上.volatile限定修饰符的用法与const非常相似--都是作为类型的附加修饰符.例如: display_register是一个int型的volatile对象:curr_task是一个指向volatile

Linux中volatile关键字的作用

一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问.另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度.以上是硬件级别的优化.再看软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化.编译器优化常用的方法有:将内存变量缓存到寄存器:调整指令顺序充分利用CPU指令流水线,常见的是重新排序读写指令.对常规内存进行优

JAVA synchronized关键字锁机制(中)

synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选. 下面总结其特性以及使用技巧,加深对其理解. 特性: 1. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.       2. 当一个线程同时访问object的一个synchronized(this)同步代码块时,其它线程仍然可以访问非修饰的方法或代码块.       3. 当多个线程同时访问object的synchronized(this)同步代码

Java 中几个重要的关键字

Java中的关键字特别多,大致如下: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends final implements interface native new static strictfp synchronized transient volatile 程序控制 break continue return do while if else for instanceof switch case default 异常

RobotFramework自动化测试框架的基础关键字(五)

1.1.1        Run Keyword If判断的使用 Run Keyword If是一个常用的用来做逻辑判断的关键字,意思是如果满足了某一个判断条件,然后就会执行关键字,我们对list3中放入0,1,2三个元素,然后遍历list3,判断当取到元素为0时,我们输出"男生". @{list3} Create List      0     1     2 :FOR       ${value} in    @{list3} Run Keyword If        '${va

this关键字的使用

* this关键字的使用: * 1.this:可以理解为:当前对象 或 当前正在创建的对象 * * 2.this可以用来调用:属性.方法.构造器 * * 3.this调用属性.方法 * 在方法中:我们可以在方法中通过"this.属性"或者"this.方法"的方法,表示调用当前对象的指定属性或方法.但是通常 * 情况下,我们都省略了"this.".但是如果方法的形参和当前对象的属性名相同的情况下,我们必须显式的使用"this.变量&quo

关键字和继承

1.关键字的使用 2.继承