volatile的意義是:
比如兩個線程在運行中。第一個線程已經初始化,將變量a載入了緩存後,這時候第二個線程改變了a的值。如果a沒有用volatile修飾的話,那麼可 能在第一個線程中使用a時,還是使用的緩存中沒有改變過的值。(這只是一個可能性,因爲多線程的運行誰都不能保證結果是什麼,這是與不同的系統有關的)。 如果使用了volatile修飾,那麼保證每次取a的值都不是從緩存中取,而是從a所真正對應的內存地址中取.
volatile的本意是“易變的”
由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化。比如:
static int i=0;
int main(void)
{
...
while (1)
{
if (i) dosomething();
}
}
/* Interrupt service routine. */
void ISR_2(void)
{
i=1;
}
程序的本意是希望ISR_2中斷產生時,在main當中調用dosomething函數,但是,由於編譯器判斷在main函數裏面沒有修改過i,因此可能只執行一次對從i到某寄存器的讀***作,然後每次if判斷都只使用這個寄存器裏面的“i副本”,導致dosomething永遠也不會被調用。如果將將變量加上volatile修飾,則編譯器保證對此變量的讀寫***作都不會被優化(肯定執行)。此例中i也應該如此說明。
1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile;
2、多任務環境下各任務間共享的標誌應該加volatile;
3、存儲器映射的硬件寄存器通常也要加volatile說明,因爲每次對它的讀寫都可能由不同意義;
另外,以上這幾種情況經常還要同時考慮數據的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2中可以禁止任務調度,3中則只能依靠硬件的良好設計了。