volatile关键字

来源:互联网 发布:达芬奇 知乎 编辑:程序博客网 时间:2024/06/04 18:59
    volatile是我们c语言中的一个关键字,但是c++是站在巨人的肩膀上,它是基于c语言开发的,所以它也有volatile关键字,那什么是volatile关键字呢,我们可能平常可能不怎么用,但是却是很有必要了解一下,今天我们就来说说volatile的用法。
   一、  volatile的作用
            1、防止编译器对汇编指令顺序上的优化:
            2、防止寄存器存储变量的副本值,应用于多线程中。

二、示例分析
            1、int gdata=10;
                  void func()
{
                  gdata++;
}

thread 1
func();
//假如 我们运行到,2)还没来得及把寄存器里的值写回去。然后时间片完了,要做thread2了。
thread 2
int b=gdata;   //并不能得到正确的值,我们寄存器了加完的值还没有写回内存。

还有一个就是 我们gdata是后置++,这个我们是先使用后加加,但是因为我们编译器可能认为程序之后还有使用,为了提高执行效率,它选择了先不将寄存器里的值写回,也就是说先不做3),把3)这个写回放在后面去,这两个问题都是第一条问题,防止编译器对汇编指令的优化,保证得到正确的值。

那修改方式:
volatile int gdata=10;
这样用volatile修饰之后,编译器就不会对它的指令顺序进行优化。当然第一个gdata++并不是一个原子操作,还需要借助同步原语,让它正确执行。

2、
int a=10;
void func()
{
     a=20;
}

thread 1
func()

thread 2
int b=a;
mov eax,dword ptr[a];
mov dword ptr[b],eax;  
int c=a;
mov dword ptr[c],eax;
因为编译器认为两条语句之间就没有修改过a,所以它就直接从寄存器中取值,不会先从内存中取,但是如果执行完前面的b=a之后,线程2时间片完了,然后执行线程1,这个时候a的值已经变了,但是我们回到线程2的时候却依然用的是第一次拿出来放在寄存器中的值,所以就发生了错误。
          

volatile和const的用法很像
volatile int a=10;     //表示a的是volatile的
volatile int *b=&a;   //表示b所指向的值是是volatile的,也就是a
volatile int * volatile c=&a; //表示c是volatile的指针,而指向的值也是volatile类型的。

留一个题目大家可以思考一下,volatile和const的区别
原创粉丝点击