嵌入式之volatile关键字

0 引言

  在计算机中,CPU对RAM的访问速度远远慢于处理速度,而访问寄存器要比访问内存单元快的多。因此在存取变量时,为提高存取速度,编译器有时会优化代码:先把变量存放到一个寄存器中,以后使用该变量值时,直接从寄存器中取值,而不是从RAM读取,从而提高性能。然而,这种优化在带来性能提升的同时,也造成了某些灾难。

1 volatile关键字的原理

  volatile的意思是“易变的”,它是一个特征修饰符,表示这个变量可能会被意想不到地改变。也就是说,volatile告诉编译器:后面所定义的变量随时都有可能改变,因此不要对这个变量的存取进行优化,每次存取这个变量时,都直接访问变量的原始地址,而不是通过寄存器。如果没有volatile关键字,则编译器可能优化存取,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

2 volatile关键字的使用场合

  volatile“易变”是因为外在因素引起的,像多线程,中断等。一般来说,volatile用在以下两个地方。

  • 中断服务程序中修改的供其它程序检测的变量

  在下面的程序段中,编译器判断主函数里面没有修改变量 i ,因此可能将变量 i 的值读取到某寄存器中,往后对变量 i 的读取,就只是从该寄存器中读取变量 i 的副本。然而,当中断触发后,变量 i 在中断程序中修改了,而主函数却并不知情,还在对寄存器中的错误副本进行读取,这就使得中断没有发生一样。

static int i = 0;
int main(void)
{
    while(1)
    {
        if(i)
            dosomething();
    }
}
/*Interrupt service routine.*/
void ISR(void)
{
    i=1;
}

  • 多任务环境下各任务间共享的变量

  在线程1中, 当读取一个变量时,编译器优化时可能会先把变量读取到一个寄存器中,以后再取变量值时,就直接从寄存器中取值(当然,在线程1中改变变量的值,寄存器会相应改变);当该变量的值在线程2中被改变后,寄存器的值并不会相应改变,从而造成线程1中读取的值和实际的值不一致的情况。

3 总结

  volatile关键字是一种类型修饰符,用它声明的类型变量在每次需要存取这个变量的时候,都会直接通过变量内存去访问变量,禁止了编译器的优化。对合适的变量使用volatile能够减少很多不必要的麻烦,但是频繁地使用volatile很可能会增加代码尺寸和降低性能。总的来说,因此要合理的使用volatile关键字,在必要时再使用。

发布了2 篇原创文章 · 获赞 0 · 访问量 116

猜你喜欢

转载自blog.csdn.net/Zhupeizhao/article/details/105588390