1.volatile 修饰符。
被设计 用来修饰 不同线程访问 和修改的 变量。如果不加volatile .基本上会导致:无法编写多线程程序,或者失去大量优化机会。
2.作用
作为指令的关键字,确保本条指令,不会因为编译器的优化而省略,要求每次直接读值。即防止编译器 对代码进行优化。
XBYTE[2]=0X55;
XBYTE[2]=0X56;
XBYTE[2]=0X57;
XBYTE[2]=0X58;
对外部硬件而言,四条语句,代表不同操作,产生四个不同动作。但是,编译器会对语句进行优化,认委只有 XBYTE[2]=0X58;而忽略前三条,如果加上volatile ,则逐条编译。
3.举例。
优化器,在每次用到这个变量时,必须每次重新读取这个变量的值,而不是读取 寄存器中的 备份。
int squre(volatile int* &ptr){
int a,b;
a=*ptr;
b=*ptr;
return a*b;
}
结果,可能并不是 所期待的平方之,因为 执行过程中,两次取值可能会发生改变。
关键在于两个地方:
(1)编译器的优化
本次线程内,当读取一个变量,为了提高存取速度,编译器 优化时,会把一个变量读取到寄存器中。以后再取变量,就直接从寄存器读取。当变量值在本线程发生改变,会把变量的新值,从新copy到寄存器/。保持一致。
当别的线程改变了值,寄存器的值不会发生改变,造成应用程序的值和实际 变量值不一样。
(2)出现情况。
用volatile 修饰的变量, 可以被 编译器 未知的因素更改,如 操作系统,硬件,或者其他线程等。 遇到该关键字 声明,编译器 不再对该 变量的代码进行优化,从而可以提供对特殊地址的特殊访问。
系统总是重新从内存读取数据,即使该指令刚处理过,并且被立刻保存。
如 测试空循环 执行速度:
for(int i=0;i<10000;i++); 编译器会把它优化掉,根本不执行。
for(volatiile int i=0;i<10000;i++); 使用volatile 声明后,就会执行。