c++中volatile關鍵字的使用詳解了解volatile關鍵字之前,需要了解:乙個變數被編譯器編譯時,會在暫存器上建立乙個副本(這一步叫優化,因為cpu訪問暫存器的速度要快過ram,相當於加快了程式訪問這個變數的速度)。詳解c/c++中volatile關鍵字
詳解volatile在c++中的作用
隨機訪問儲存器(random access memory,ram),也叫主存,是與cpu直接交換資料的內部儲存器。它可以隨時讀寫(重新整理時除外),而且速度很快,通常作為作業系統或其他正在執行中的程式的臨時資料儲存介質。ram工作時可以隨時從任何乙個指定的位址寫入(存入)或讀出(取出)資訊。它與rom的最大區別是資料的易失性,即一旦斷電所儲存的資料將隨之丟失。ram在計算機和數字系統中用來暫時儲存程式、資料和中間結果。volatile給編譯器的指示:對它所修飾的物件不應該執行優化。volatile提醒編譯器它後面所定義的變數隨時都有可能改變,因此編譯後的程式每次需要儲存或讀取這個變數的時候,都會直接從變數位址中讀取資料。
volatile的作用就是用來進行多執行緒程式設計。
如果乙個基本變數被volatile修飾,編譯器將不會把它儲存到暫存器中,而是每一次都去訪問記憶體中實際儲存該變數的位置上。這一點就避免了沒有volatile修飾的變數
在多執行緒的讀寫中所產生的由於編譯器優化所導致的災難性問題。所以多執行緒中必須要共享的基本變數一定要加上volatile修飾符。當然了,volatile還能讓你在編譯時期捕捉到非執行緒安全的**。
class
student
}void
eat().
..private
:bool flag =
false;}
;
上面程式的本意是:當呼叫eat()
函式時,將開飯標誌flag
置為true,但是在編譯時,編譯器會優化flag
變數,在暫存器建立相同的副本。此時,在多執行緒中,另乙個執行緒啟用了開飯標誌(將flag
置為true),但是暫存器中的副本並未改變,就導致原來位址上的「真」開飯標誌flag
被忽略掉了。所以,這個開飯標誌需要修改為:volatile bool flag = false;
如果變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)
1、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
2、多工環境下各任務間共享的標誌應該加volatile;
3、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;
關於類的話,首先如果類是volatile則裡面的成員都是volatile的。
其次要將成員函式宣告為volatile則同const一樣在函式最後宣告即可。
當你設計乙個類的時候,你宣告的那些volatile成員函式是執行緒安全的,所以那些隨時可能被呼叫的函式應該宣告為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 關鍵字,看看有什麼變化:
#include
void
main()
int b = i;
printf
("i = %d"
, b)
;}
分別在 debug 和 release 版本執行程式,輸出都是:
i = 10
i = 32
這說明這個 volatile 關鍵字發揮了它的作用。其實不只是「內嵌彙編操縱棧」這種方式屬於編譯無法識別的變數改變,另外更多的可能是多執行緒併發訪問共享變數時,乙個執行緒改變了變數的值,怎樣讓改變後的值對其它執行緒 visible。 三 this關鍵字
this關鍵字表示當前類的物件,可以通過this.呼叫方法和屬性或者用this 呼叫構造方法,方便分別成員變數和區域性變數 語法 this.屬性 public class catpublic void setname string name public intgetage public void ...
1 static 關鍵字 演算法cpp
2.靜態全域性變數有以下特點 3.該變數在全域性資料區分配記憶體 4.未經初始化的靜態全域性變數會被程式自動初始化為0 自動變數的值是隨機的,除非它被顯式初始化 5.靜態全域性變數在宣告它的整個檔案都是可見的,而在檔案之外是不可見的 6.靜態區域性變數有以下特點 7.該變數在全域性資料區分配記憶體 ...
new關鍵字 this關鍵字 base關鍵字
使用new,所做的三件事 1.類是引用物件,引用物件是在堆中開闢空間 在堆中開闢空間 2.在開闢的堆空間中建立物件 3.呼叫物件的構建函式 4.隱藏父類成員 子類的成員可以與隱藏從父類繼承的成員,類似於重寫。public new void sayhello this關鍵字的使用 1.代表當前類的物件...