和const對應,const表示變量是恆定不變的,而Volatile則相反,表示變量隨時均可能被改變,所以每次獲取變量都須要從新到內存中獲取;多線程
有這樣的代碼:優化
int i = 10;spa
int a = i;線程
...debug
int b = i;進程
printf("a=%d,b=%d", a, b);內存
在debug模式下,代碼沒有被優化過,咱們能獲得a=10,b=10這樣的結果,可是在Release模式下,會執行代碼優化,編譯器執行到int i = 10時會將i存入寄存器中,當執行到int b = i這一行時,發現i從int i = 10以後都沒有被改變過,所以會將保存到寄存器中的i直接賦值給b,假定在此期間某個外部因素改變了i的值,編譯器是不知道的,所以這個時候的i和寄存器中的i數值是不同的,寄存器中的i並非最新的內存數據。編譯器
bool bChanged = false;string
void thread1()編譯
{
while(!bChanged){...};
}
void thread2()
{
bChanged = true;
}
運行線程2後線程1是不會中止的,緣由就在於線程1已經將bChanged從內存讀取到CPU寄存器中,bChanged的內存改變線程1是沒法知道的,要讓代碼能正確執行,除非關閉Release模式下的代碼優化功能。
程序和其餘進程或系統進程經過共享內存訪問數據時,其餘進程能夠隨時改變內存中的數據,此時不管你執行多少次int a = i,int b = i; int c = i;可能都沒法獲得最新的i值,仍是由於寄存器拷貝的問題;一樣還有訪問端口數據,其實和訪問內存數據同樣。好比硬件將參數映射到內存的某個區域,程序經過一個struct來讀取參數結構:
struct myparam {
int x;
int y;
long size;
long size;
char[32] name;
}PMYPARM;
PMYPARM yParam = (PMYPARM)memory_addr;
此時yParam指向的是一段真實的,且不容改變地址的內存地址,然而系統的其餘進程在不斷的刷新這段內存區域(內存區域是能夠被多核CPU同時訪問的,只要獲取到總線控制權便可),所以每次取回的數據均可能不同。
定義這個關鍵字就是要告訴編譯器,每次取得該變量的值,都須要到內存中獲取:
volatile int i = 10;
int a = i;從新到內存中取得i的數據賦值給a;
int b = i;從新到內存中取得最新的數據賦值給b;
int c = i;從新到內存中獲取i的最新數據。
上面的結構體能夠這樣定義:
volatile PMYPARM yParam = (PMYPARM)memory_addr;
定義一個可變的結構體,每次訪問其成員時都須要從新從內存獲取最新的數據:
int x = yParam.x;
long size = yParam.size;
string name(yParam.name);