volatile變數的概念及用法

2021-09-26 18:57:04 字數 2346 閱讀 1397

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

int i = 5;

int a = i;

int b = i;

編譯器發現兩次從i讀資料的**之間,並沒有對i進行過操作,它會自動把上次讀的資料放在b中,而不是重新從i裡面讀;

volatile 的意思是「易失的,易改變的」。這個限定詞的含義是向編譯器指明變數的內容可能會由於其他程式的修改而變化。通常在程式中申明了乙個變數時,編譯器會盡量把它存放在通用暫存器中,例如ebx。當cpu把其值放到ebx中後就不會再關心對應記憶體中的值。若此時其他程式(例如核心程式或乙個中斷)修改了記憶體中它的值,ebx中的值並不會隨之更新。為了解決這種情況就建立了volatile限定詞,讓**在引用該變數時一定要從指定位置取得其值。

關鍵字volatile有什麼含意?

並給出三個不同的例子。 乙個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是volatile變數的幾個例子:

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

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

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

嵌入式系統程式設計師經常同硬體、中斷、rtos等等打交道,所用會經常要求定義為volatile型別的變數。

volatile int ncount;

當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。

volatile的本意是「易變的」

由於訪問暫存器的速度要快過ram,所以編譯器一般都會作減少訪問外部ram的優化。比如:

static

int i=0;

intmain

(void)}

/* interrupt service routine. */

void

isr_2

(void

)

程式的本意是希望isr_2中斷產生時,在main當中呼叫dosomething函式,但是,由於編譯器判斷在main函式裡面沒有修改過i,因此

可能只執行一次對從i到某暫存器的讀操作,然後每次if判斷都只使用這個暫存器裡面的「i副本」,導致dosomething永遠也不會被呼叫。如果將將變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。

一般說來,volatile用在如下的幾個地方:

1、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;

2、多工環境下各任務間共享的標誌應該加volatile;

3、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;

另外,以上這幾種情況經常還要同時考慮資料的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2中可以禁止任務排程,3中則只能依靠硬體的良好設計了。

乙個引數既可以是const還可以是volatile嗎?解釋為什麼。

回答:可以是。例如對於唯讀的狀態暫存器而言,如果它僅僅是volatile型別,那麼它還是可能被意想不到的改變。但它還是const的時候,程式就不應該試圖去修改它。

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

回答:可以是的。儘管這種情況並不常見,但它還是可以。

乙個例子就是:當乙個中斷服務子程式企圖去修改乙個指向乙個buffer指標的時候。

下面的函式有什麼錯誤:

int

square

(volatile

int*ptr)

回答:這段**可能有點惡作劇的味道。但它很好說明volatile型別引數的含義和作用。

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

int

square

(volatile

int*ptr)

由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不

是你所期望的平方值!正確的**如下:

long

square

(volatile

int*ptr)

PHP學習筆記 變數概念及使用

變數 php是一種動態 開發的指令碼語言,動態語言特點是互動性,互動性就會有資料的傳遞,而 php 作為 中間人 需要進行資料的傳遞,傳遞的前提就是php能自己儲存資料 臨時儲存 這就需要變數 變數基本概念 變數 於數學,是計算機語言中能儲存計算結果或能表示值抽象概念 變數可以通過變數名訪問,在指令...

DATA GUARD的概念及作用

data guard的最主要的功能是冗災。當然根據配置的不同,data guard還可以具備以下特點 高可用 效能提公升 資料保護以及故障恢復等。data guard可以分為物理standby和邏輯standby兩種。二者的最大差別在於,物理standby應用的是主庫的歸檔日誌,而邏輯standby...

ROM,RAM,SRAM,DRAM的概念及區別

rom和ram都是常見的儲存器,本文主要梳理rom,ram,sram,dram的概念及區別,屬於較簡單的介紹。早期的概念中,rom是唯讀儲存器 read only memory 的簡稱,從名字可以看出,rom只能讀取已經存好的資料,當資料一旦儲存完成後,就無法將之修改或者刪除,系統電源關閉後,資料也...