Cpp關鍵字破解(三) volatile 篇

2021-10-22 09:45:16 字數 2289 閱讀 7214

c++中volatile關鍵字的使用詳解

詳解c/c++中volatile關鍵字

詳解volatile在c++中的作用

了解volatile關鍵字之前,需要了解:乙個變數被編譯器編譯時,會在暫存器上建立乙個副本(這一步叫優化,因為cpu訪問暫存器的速度要快過ram,相當於加快了程式訪問這個變數的速度)。

隨機訪問儲存器(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.代表當前類的物件...