關於volatile修飾符

2021-05-27 21:43:43 字數 1208 閱讀 4862

volatile是乙個型別修飾符(type specifier)。它是被設計用來修飾被不同執行緒訪問和修改的變數。如果沒有volatile,基本上會導致這樣的結果:要麼無法編寫多執行緒程式,要麼使編譯器失去大量優化的機會。

乙個定義為volatile的變數是說:這變數可能會被意想不到地改變(這種意外不是說該變數有癲癇,自己隨便變,而是說可能因為其他程式、執行緒、硬體、中斷等操作,造成對當前程式或執行緒不可知的改變,比較好理解就是多執行緒的共享變數,可能隨時存在當前執行緒無法預知的改變),這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。

這裡涉及到編譯器的編譯優化:在當前執行緒內, 當讀取乙個普通變數時,為提高訪問速度,編譯器優化時會先把變數讀取到乙個暫存器中;以後,再取變數值時,就直接從暫存器中取值;當變數值在本執行緒裡改變時,會同時把變數的新值copy到該暫存器中,以便保持一致。但當變數在因別的執行緒等而改變了值,當前執行緒並不會得到通知,當前執行緒的該暫存器值不會相應改變,從而造成當前執行緒讀取的值和實際的變數值不一致。嗯,就是這樣!

1). 並行裝置的硬體暫存器(如:狀態暫存器)

2). 乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)

3). 多執行緒應用中被幾個任務共享的變數

然後,我們需要了解volatile的幾個疑問:

1). 乙個引數既可以是const還可以是volatile嗎?為什麼。

2). 乙個指標可以是volatile 嗎?解釋為什麼。

3). 下面的函式有什麼錯誤:

int square(volatile int *ptr)

下面是答案:

1). 是的。乙個例子是唯讀的狀態暫存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。

2). 是的。儘管這並不很常見。乙個例子是當乙個中斷服務子程式修改乙個指向乙個buffer的指標時。

3). 這段**是個惡作劇。這段**的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向乙個volatile型引數,編譯器將產生類似下面的**:

int square(volatile int *ptr)

由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不是你所期望的平方值!正確的**如下:

long square(volatile int *ptr)

volatile型別修飾符的作用

volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改,比如 作業系統 硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。使用該關鍵字的例子如下 int volatile nvint 當要求使...

volatile型別修飾符的使用

儘管c和c 標準對於執行緒都明顯的 保持沉默 但它們以volatile關鍵字的形式,確實為多執行緒保留了一點特權。就象大家更熟悉的const一樣,volatile是乙個型別修飾符 type modifier 它是被設計用來修飾被不同執行緒訪問和修改的變數。如果沒有volatile,基本上會導致這樣的...

修飾符 許可權修飾符

四種形式許可權修飾符的訪問情況 publicprotected不寫private 同乙個類中 四種都可以 同一包中的不同類 除了private剩下都可以 不同包下的子類 public protected 可以 不同包下的不同類 只有public可以 許可權修飾符 public protected 預...