C語言--volatile關鍵字

因時間原因還沒有對volatile關鍵字進行總結,先放上幾個不錯的總結博客,以防後續遺忘。

1、《C語言再學習 -- 關鍵字volatile》

2、《C語言中volatile的用法及意義》

3、《詳解C中volatile關鍵字》

 

以下幾種情況需要用到volatile關鍵字:

1、並行設備的硬件寄存器(如:狀態寄存器)

存儲器映射的硬件寄存器通常也要加 voliate,因爲每次對它的讀寫都可能有不同意義。     

       #define GPC1CON *((volatile unsigned int*)0xE0200080)
       #define GPC1DAT *((volatile unsigned int*)0xE0200084)
       #define GPC1PUD *((volatile unsigned int*)0xE0200088)

       2、一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)

      由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化,例如:

static int i=0; //i 爲非自動變量
int main(void)
{
     ...
     while (1){
     //由於編譯器判斷在 main 函數裏面沒有修改過 i,因此可能只執行一次對從i到某寄存器的讀操作,
     //然後每次if判斷都只使用這個寄存器裏面的“i副本”,導致 dosomething 永遠也不會被調用。
     if (i) dosomething();
   }
}
/* Interrupt service routine. */
void ISR_2(void)
{
      i=1;
}

3、多線程應用中被幾個任務共享的變量

當兩個線程都要用到某一個變量且該變量的值會被改變時,應該用 volatile 聲明,該關鍵字的作用是防止優化編譯器把變量從內存裝入CPU寄存器中。如果變量被裝入寄存器,那麼兩個線程有可能一個使用內存中的變量,一個使用寄存器中的變量,這會造成程序的錯誤執行。volatile的意思是讓編譯器每次操作該變量時一定要從內存中真正取出,而不是使用已經存在寄存器中的值。
 

volatile  BOOL  bStop  =  FALSE;  //bStop  爲共享全局變量
(1) 在一個線程中:  
  while(  !bStop  )  {  ...  }  
  bStop  =  FALSE;  
  return;    
 
(2) 在另外一個線程中,要終止上面的線程循環:  
  bStop  =  TRUE;  
  while(  bStop  ); 

等待上面的線程終止,如果bStop不使用volatile申明,那麼這個循環將是一個死循環,因爲bStop已經讀取到了寄存器中,寄存器中bStop的值永遠不會變成FALSE,加上volatile,程序在執行時,每次均從內存中讀出bStop的值,就不會死循環了。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章