volatile簡單理解
阿新 • • 發佈:2018-11-03
程式碼例子理解:
作者:KE meng連結:https://www.zhihu.com/question/31459750/answer/52061391
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
來看這個程式碼:
int fun(int& a) { int b = a; int c = a; return a+b+c; } int main() { int a=1; //.........做一些和a無關的事 return fun(a); }
這個程式碼是很好優化的,因為編譯器知道a的值是1,參考上下文,編譯器又能知道b和c的值也是1,
而且根本沒有人用到了a,b,c三個變數,也沒有任何人在修改a,b,c三個的值,所以編譯器可能就直接
把這個函式優化成:
int main() { return 3; }
了.
這麼優化有什麼問題嗎? 單執行緒沒問題,但多執行緒就有問題了,如果是多執行緒,
a的值雖然在當前上下文中不會被修改,但可能正在被其他執行緒修改啊.於是上面的優化
就不對了. 那麼,volatile關鍵字在這裡就可以幫助我們了,volatile關鍵字提醒編譯器:
a可能隨時被意外
意外的意思是雖然當前這段程式碼裡看起來a不會變,但可能別的地方正在修改a的值哦.
所謂"別的地方",某些情況下指的就是其他執行緒了.
那麼,如果把程式碼修改如下:
int fun(volatile int& a)
{
int b = a;
int c = a;
return a+b+c;
}
int main()
{
volatile int a=1;
//.........做一些和a無關的事
return fun(a);
}
編譯器就不敢優化了:
int fun(volatile int& a) { int b = a; //這裡從記憶體讀一下a吧,誰知道a還等不等於1呢 int c = a; //這裡再從記憶體讀一下a吧,誰知道a還等不等於1呢 return a+b+c; //這裡也從記憶體讀一下a吧,誰知道a還等不等於1呢 } int main() { volatile int a=1; //.........做一些和a無關的事 return fun(a); //完全不敢優化啊,鬼知道a變成多少了.... }
總結:被volatile修飾的變數,有執行緒使用到該變數時都會去主記憶體裡面讀取以保證“最新”。
加鎖物件obj:A執行緒使用了obj,此時B執行緒無法使用,A執行緒操作obj時直接使用自己工作記憶體中的obj副本,但不保證A執行緒在使用
的obj副本是最新的。
加鎖物件obj並用volatile:A執行緒使用obj,此時B執行緒無法使用,並且obj是從主記憶體中取的,在加鎖的情況下可以保證該obj是最新的。