我閱讀了關於volatile關鍵字,但我不知道在什麼情況下我應該使用它。哪裏可以使用volatile?
當內存(變量)得到更新,進程沒有意識到這一點?
驅動程序在什麼情況下會使用volatile變量?
我閱讀了關於volatile關鍵字,但我不知道在什麼情況下我應該使用它。哪裏可以使用volatile?
當內存(變量)得到更新,進程沒有意識到這一點?
驅動程序在什麼情況下會使用volatile變量?
在我的世界中最常見的情況是當你編程使用內存映射I/O的微控制器時。由於外部數字輸入,寄存器中的值可能會發生變化,但如果您沒有聲明變量爲volatile
,則編譯器可能會完全優化代碼,您會想知道爲什麼沒有任何效果。
Matt建議我修改關於代碼獲得「優化」的聲明。內存映射I/O通過指針訪問代碼。當你想檢查一個按鈕的狀態時,你通常會將該寄存器的值與按鈕的位掩碼進行按位與運算。如果你沒有指定volatile,編譯器會說:「嘿,你的代碼永遠不會改變這個指針的值,所以我會在你把它與位進行與運算的時候刪除那個語句,因爲這個值總是一樣!」。
希望這可以清楚我的發言。感謝您的建議,馬特。
你應該進入「優化它」的意思,而我們中的一些人熟悉這意味着什麼,它可能不適用於所有人。 – 2010-09-06 06:29:32
正如您所標記這個與linux-device-driver
標籤這可能會對你有所幫助
,Linux內核中的編碼一些具體的建議可能是爲了。
一般情況下,您不需要在您的Linux內核代碼中編寫volatile
。在可能需要volatile
的情況下,它的使用被封裝在您應該調用的核心內核函數中。例如,如果你正在做內存映射I/O,那麼你就應該使用ioremap()
,writel()
等
從我所知,在C應使用readl()
的volatile
關鍵字,其中併發非同步操作執行上來自多個來源(過程)的變量。如果變量聲明爲volatile
,則所有進程將始終直接從其存儲器位置訪問該變量,而不是將該變量複製到微處理器的高速緩存中並從那裏訪問該變量。
請注意,這將顯着降低該特定變量的性能。內存中變量的訪問時間以毫秒爲單位,而對於第1級或第2級緩存變量,它大約在十分之幾納秒左右,因此只有在考慮了所有其他選項時才使用它們。
是否可以對來自多個源(進程)的變量進行併發的非同步操作? – Pointer 2010-09-06 08:13:39
@Yogesh:是的。最簡單的例子是一個從信號處理程序寫入並在程序主循環中讀取的變量(例如,「清理並終止asap」標誌)。其他包括各種形式的共享內存,如共享內存映射文件。 – 2010-09-06 12:26:39
除了其他人所說的,volatile關鍵字通常是爲了防止編譯器形式進行優化。 在某些內存映射寄存器中,寄存器的值保持在chinagin上,如使用rtc時鐘值的volatile關鍵字。 看看這個例子:
RTC_CLOCK _time;
TIME _currentTime = _time ;
while(_currentTime - _time >= 100)
{
//Do something
}
//rest of the code
如果我們不把這段代碼時間之前會是這樣的_currentTime volatile關鍵字 - _time = 0,編譯器不會考慮它下面的while循環:
RTC_CLOCK _time;
TIME _currentTime = _time ;
//rest of the code
爲了防止發生這種情況,我們必須在TIME中使用volatile關鍵字。
優秀的混凝土,易於理解的答案。並沒有充滿關於它如何幫助併發的虛假廢話。 – 2013-09-13 03:07:17
請參閱:http://stackoverflow.com/questions/2535148/volatile-qualifier-and-compiler-reorderings(雖然另一個問題有C++和C標籤都記住C++從C獲得了這個關鍵字)。 – dirkgently 2010-09-06 06:18:32
From Dr Dobbs - http://www.drdobbs.com/184403766;jsessionid=4HI2GRADWCN51QE1GHRSKHWATMY32JVN – pankajt 2010-09-06 06:23:11
參見[ 爲什麼在c中需要volatile? ](http://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c)。 – 2010-09-06 06:23:33