1、什麼是volatile
volatile關鍵字是一種限定符用來宣告乙個物件在程式中可以被語句外的東西修改,比如作業系統、硬體或併發執行執行緒。
遇到該關鍵字,編譯器不再對該變數的**進行優化,不再從暫存器中讀取變數的值,而是直接從它所在的記憶體中讀取值,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。
下面寫個**測試一下volatile關鍵字
注:vc6.0中一般除錯模式沒有進行**優化,所以這個關鍵字的作用看不出來。下面通過插入彙編**,測試有無 volatile 關鍵字,對程式最終**的影響:
#include void main()
int b = i;
printf("i = %d", b);
}
結果
在 debug 版本模式執行程式:
i = 10 i = 32
在release版本模式下執行程式:
i = 10 i = 10
上述 輸出的結果明顯表明,release 模式下,編譯器對**進行了優化,第二次沒有輸出正確的 i 值。下面,我們把 i 的宣告加上 volatile 關鍵字(在這裡不再貼**,就是上面的**i前面加上volatile)
結果顯示:在debug和release版本模式下執行程式
i = 10 i =32
這就是表示volatile關鍵字發揮了作用
2、volatile在哪兒使用
一般說來,volatile用在如下的幾個地方:
(1)、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
(2)、多工環境下各任務間共享的標誌應該加volatile;
(3)、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能有不同意義;
另外,以上這幾種情況經常還要同時考慮資料的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2 中可以禁止任務排程,3中則只能依靠硬體的良好設計了。
3、多執行緒下的volatile
當兩個執行緒都要用到某乙個變數且該變數的值會被改變時,應該用volatile宣告,該關鍵字的作用是防止優化編譯器把變數從記憶體裝入cpu暫存器中。如果變數被裝入暫存器,那麼兩個執行緒有可能乙個使用記憶體中的變數,乙個使用暫存器中的變數,這會造成程式的錯誤執行。volatile的意思是讓編譯器每次操作該變數時一定要從記憶體中真正取出,而不是使用已經存在暫存器中的值,如下:
volatile bool bstop = false;
// (1) 在乙個執行緒中:
while( !bstop )
bstop = false;
return;
//(2) 在另外乙個執行緒中,要終止上面的執行緒迴圈:
bstop = true;
while( bstop ); //等待上面的執行緒終止,
如果bstop不使用volatile申明,那麼這個迴圈將是乙個死迴圈,因為bstop已經讀取到了暫存器中,暫存器中bstop的值永遠不會變成false,加上volatile,程式在執行時,每次均從記憶體中讀出bstop的值,就不會死迴圈了。
參考:
c volatile關鍵字解析
volatile提醒編譯器它後面所定義的變數隨時都有可能改變,因此編譯後的程式每次需要儲存或讀取這個變數的時候,都會直接從變數位址中讀取資料。如果沒有volatile關鍵字,則編譯器可能優化讀取和儲存,可能暫時使用暫存器中的值,如果這個變數由別的程式更新了的話,將出現不一致的現象。下面舉例說明。在d...
C volatile關鍵字的使用
前言 volatitle是什麼?volatile 的字面意思為 不穩定的,易變的 它是被設計用來修飾被不同執行緒訪問和修改的變數,每次讀取變數都從變數的記憶體位址中訪問,防止變數更新不同步。volatile為什麼用?講乙個小例子 int flag interrupt isr uart1 void m...
關鍵字const詳解
關鍵字const 1 用關鍵字const定義變數指所定義的常量。即恆定的變數,即不可改變的變數。例 const int i 10 此時 i 就是乙個整型的常量,其值不能改變。在c 中如果用const定義乙個物件,那麼物件中的成員變數就是常數,不能改變 只能為初始化的值 如果用const定義類中的成員...