MSDN手册中对volatile关键字的解释:
大概的翻译:
volatile关键字是一个类型限定符,用于声明一个对象可以通过其他语句(例如操作系统、硬件或并发执行的线程)在程序中进行修改。
volatile关键字的两个功能:
(1)防止编译器对汇编指令做顺序上的优化。
(2)防止寄存器存储变量的副本值。 应用在多线程中
int gdata=10;//全局变量
int fun(){
gdata=20;
}
thread1线程1{
fun();
}
thread2线程2{
int a=gdata;
//mov eax,dword ptr[gdata]
//mov dword ptr[c],eax
int c=gdata;//mov dword ptr[c],eax
//为了优化指令,编译器认为两次赋值中间没有对gdata进行赋值
//第二次对c赋值使用gdata存储在寄存器eax的副本值
/*实际上会存在这样的情况,由于时间片轮转技术。当分配给线程2时间
片用完时,恰巧将mov dword ptr[c],eax执行完毕。此时,时间片分
线程1,当线程1执行完毕后,gdata=20。时间片再次分配给线程1,现场
恢复后,int c=gdata用的暂存在eax寄存器中的gadta=10,而此时
gdata=20,显然时错误的*/
//因此,为了防止类似这样的错误,可以加volatile关键字,防止寄存器
//存储变量的副本值
}
指令的调优
1.编译器对指令的调优 使用volatile
关键字
void fun(int *a){*a=10;int b=*a;}
//上述的代码,进过汇编编译器可能优化汇编指令为:
void fun(int *a){int b=*a;*a=10;}
//如果不需要或防止编译器对汇编指令作顺序的优化,添加volatile关键字限定
void fun(volatile int* a){*a=10;int b=*a}
2.程序执行时cpu对指令的调优 barrier()
当程序开始执行时,由于CPU的流水线技术,可能会对指令进行顺序上的调优。以达到指令级并行,提高指令执行的速度。但是如果程序员不希望发生顺序的调优,则可在可能发生调优的上下程序段之间添加barrier();
以防止CPU对指令的调优。