vay0721 博主總結的挺好的
傳送門做一些摘要
volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改,比如:作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行優化,從而可以提供對特殊位址的穩定訪問。
直接訪問原始記憶體位址
簡單地說就是防止編譯器對**進行優化
xbyte[2]=0x55;
xbyte[2]=0x56;
xbyte[2]=0x57;
xbyte[2]=0x58;
對外部硬體而言,上述四條語句分別表示不同的操作,會產生四種不同的動作,但是編譯器卻會對上述四條語句進行優化,認為只有xbyte[2]=0x58(即忽略前三條語句,只產生一條機器**)。如果鍵入volatile,則編譯器會逐一地進行編譯並產生相應的機器**(產生四條**)。
精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。
一般說來,volatile用在如下的幾個地方:
1、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
2、多工環境下各任務間共享的標誌應該加volatile;
3、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能有不同意義;
另外,以上這幾種情況經常還要同時考慮資料的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2 中可以禁止任務排程,3中則只能依靠硬體的良好設計了。
在本次執行緒內,當讀取乙個變數時,為提高訪問速度,編譯器優化時有時會先把變數讀取到乙個暫存器中;以後再取變數值時,就直接從暫存器中取值;
當變數值在本執行緒裡改變時,會同時把變數的新值copy到該暫存器中,以便保持一致
當變數在因別的執行緒等而改變了值,該暫存器的值不會相應改變,從而造成應用程式讀取的值和實際的變數值不一致
當該暫存器在因別的執行緒等而改變了值,原變數的值不會改變,從而造成應用程式讀取的值和實際的變數值不一致。
可能出現改變的情況
1)並行裝置的硬體暫存器
2)乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)
3)多執行緒應用中被幾個任務共享的變數
volatile int i=10;
int a=i;
某個**,對i 操作
int b=i;
編譯器優化做法:
由於編譯器發現兩次從i讀資料的**之間的**沒有對i進行過操作,它會自動把上次讀的資料放在b中。而不是重新從i裡面讀。
這樣一來,如果i是乙個暫存器變數或者表示乙個埠資料就容易出錯,所以說volatile可以保證對特殊位址的穩定訪問。
volatile對應的變數可能在你的程式本身不知道的情況下發生改變
比如多執行緒的程式,共同訪問的記憶體當中,多個程式都可以操縱這個變數
你自己的程式,是無法判定何時這個變數會發生變化
還比如,他和乙個外部裝置的某個狀態對應,當外部裝置發生操作的時候,通過驅動程式和中斷事件,系統改變了這個變數的數值,而你的程式並不知道。
對於volatile型別的變數,系統每次用到他的時候都是直接從對應的記憶體當中提取,而不會利用cache當中的原有數值,以適應它的未知何時會發生的變化,系統對這種變數的處理不會做優化——顯然也是因為它的數值隨時都可能變化的情況。
static int i = 0;
int main(void)
}/*interruptserviceroutine.*/
void isr_2(void)
程式的本意是希望isr_2中斷產生時,在main當中呼叫dosomething函式,但是,由於編譯器判斷在main函式裡面沒有修改過i,因此
可能只執行一次對從i到某暫存器的讀操作,然後每次if判斷都只使用這個暫存器裡面的「i副本」,導致dosomething永遠也不會被呼叫。如果將變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。
怪不得我上次在定時器中做延時,一直沒有進入計數。
Java 開發, volatile 你必須了解一下
首先說我們如果要使用 volatile 了,那肯定是在多執行緒併發的環境下。我們常說的併發場景下有三個重要特性 原子性 可見性 有序性。只有在滿足了這三個特性,才能保證併發程式正確執行,否則就會出現各種各樣的問題。原子性,上篇文章說到的 cas 和 atomic 類,可以保證簡單操作的原子性,對於一...
C語言開發之專一王子 volatile
每個變數和他的名字一樣很善變,有時候它善變是發自內心的,有時是外部因素決定的,只有volatile變數才會表裡如一,因此獲得了專一王子的美譽 作用 volatile字面意思是易揮發,易變化的意思,它修辭的變數表示該變數的值很容易由於外部因素發生改變,強烈請求編譯器要老老實實的在每次對變數進行訪問時去...
專案開發文件之 專案開發計畫
專案開發計畫 1 引言 1.1 編寫目的 闡明編寫可行性研究報告的目的,提出讀者物件 1.2 專案背景 應包括 專案的委託單位 開發單位和主管部門 該軟體系統與其他系統的關係。1.3 定義 列出文件中用到的專門術語的定義和縮寫詞的原文 1.4 參考資料 可包括 專案經核准的計畫任務書 合同或上級機關...