1. 程式人生 > >C++中有關volatile關鍵字的作用--阻止編譯器將其變數優化快取到暫存器(和執行緒相關)(轉自百度)

C++中有關volatile關鍵字的作用--阻止編譯器將其變數優化快取到暫存器(和執行緒相關)(轉自百度)

       就象大家更熟悉的const一樣,volatile是一個型別修飾符(type specifier)。

       它是被設計用來修飾被不同執行緒訪問和修改的變數

       如果沒有volatile,基本上會導致這樣的結果:要麼無法編寫多執行緒程式,要 麼編譯器失去大量優化的機會。

      上面程式碼中Gadget::Wait的目的是每過一秒鐘去檢查一下flag成員變數,當flag被另一個執行緒設為true時,該函式才會返回。至少這是程式作者的意圖,然而,這個Wait函式是錯誤的。

假設編譯器發現Sleep(1000)是呼叫一個外部的庫函式,它不會改變成員變數 flag 那麼編譯器就可以斷定它可以把flag快取在暫存器中, 以後可以訪問該暫存器來代替訪問較慢的主機板上的記憶體。
      
      
這對於單執行緒程式碼 來說是一個很好的優化,但是在現在這種情況下,它破壞了程式的正確性: 當你呼叫了某個Gadget的Wait函式後,即使另一個執行緒呼叫了Wakeup,Wait還是 會一直迴圈下去。

這是因為flag的改變沒有反映到快取它的暫存器中去。編譯器的優化未免有點太……樂觀了。

在大多數情況下,把變數快取在暫存器中是一個非常有價值的優化方法,如果不用的話很可惜。
     
       C和 C++給你提供了顯式禁用這種快取優化的機會。如果你宣告變數是使用了volatile修飾符,編譯器就不會把這個變數快取在暫存器裡——每次訪問都將去 存取變數在記憶體中的實際位置。