多執行緒和併發 簡述volatile關鍵字

2021-09-27 04:45:15 字數 1891 閱讀 5528

一旦乙個共享變數(類的成員變數、類的靜態成員變數)被volatile修飾之後,那麼就具備了兩層含義:

使用volatile關鍵字會強制將修改的值立即寫入記憶體:使用volatile關鍵字的話,當執行緒2進行修改時,會導致執行緒1的工作記憶體中快取變數stop的快取行無效(反映到硬體層的話,就是cpu的l1或者l2快取中對應的快取行無效)

由於執行緒1的工作記憶體中快取變數stop的快取行無效,所以執行緒1再次讀取變數stop的值時會去主存讀取。

那麼執行緒1讀取到的就是最新的正確的值。

volatile關鍵字禁止指令重排有兩層意思:

當程式執行到volatile變數的讀操作或者寫操作時,在其前面的操作的更改肯定全部已經進行,且結果已經對後面的操作可見;在其後面的操作肯定還沒有進行;

在進行指令優化時,不能把volatile變數前面的語句放在其後面執行,也不能把volatile變數後面的語句放到其前面去執行

為了實現volatile的記憶體含義,加入volatile關鍵字時,編譯器在生成位元組碼時,會在指令序列中插入記憶體屏障,會多出乙個lock字首指令。記憶體屏障是一組處理器指令,解決禁止指令重排序和記憶體可見性的問題。編譯器和cpu可以在保證輸出結果一樣的情況下對指令重排序,使效能得到優化。處理器在進行重排序時是會考慮指令之間的資料依賴性。

記憶體屏障,有2個作用:

先於這個記憶體屏障的指令必須先執行,後於這個記憶體屏障的指令必須後執行。使得記憶體可見性。

所以,如果你的字段是volatile,在讀指令前插入讀屏障,可以讓快取記憶體中的資料失效,重新從主記憶體載入資料。在寫指令之後插入寫屏障,能讓寫入快取的最新資料寫回到主記憶體。

lock字首指令在多核處理器下回引發兩件事情:

將當預處理器中這個變數所在快取行的資料會寫回到系統記憶體。這個寫回記憶體的操作會引起在其他cpu裡快取了該記憶體位址的資料無效。但是就算寫回到記憶體,如果其他處理器快取的值還是舊的,在執行計算操作就會有問題,所以在多處理器下,為了保證各個處理器的快取是一致的,就會實現快取一致性協議,每個處理器通過嗅探在匯流排上傳播的資料來檢查自己快取的值是否過期,當處理器發現自己快取行對應的記憶體位址被修改,就會將當預處理器的快取行設定為無效狀態,當處理器要對這個資料進行修改操作的時候,會強制重新從系統記憶體裡把資料讀到處理器快取裡。

它確保指令重排序時不會把其後面的指令排到記憶體屏障之前的位置,也不會把前面的指令排到記憶體屏障的後面;即在執行到記憶體屏障這句指令時,在它前面的操作已經全部完成。

loadload屏障:對於這樣的語句load1;loadload;load2,在load2及後續讀取操作要讀取的資料被訪問前,保證load1要讀取的資料被讀取完畢。

storestore屏障:對於這樣的語句store1;storestore;store2,在store2及後續寫入操作執行前,保證store1的寫入操作對其他處理器可見。

loadstore屏障:對於這樣的語句load1;loadstore;store2,在store2及後續寫入操作被刷出前,保證load1要讀取的資料被讀取完畢。

storeload屏障:對於這樣的語句store1;storeload;load2,在load2及後續所有讀取操作執行前,保證store1的寫入對所有處理器可見。它的開銷是四種屏障最大的。在大多數處理器的實現中,這個屏障是個萬能屏障,兼具其它三種記憶體屏障的功能。

擴充套件:使用volatile關鍵字的場景

雙重校驗鎖dcl---使用volatile的場景之一

併發和多執行緒

併發 concurrency 某段時間內,多個任務被cpu交替處理。並行 parallelism cpu同時處理多個任務。併發打破和程式的封閉性,具有以下挑戰 1 併發程式之間有相互制約 對資源的爭搶和彼此的依賴 的關係。2 併發執行緒執行過程不連貫 斷斷續續,需要儲存和切換現場。3 設計合理的併發...

多執行緒和多程序 簡述

多執行緒可以實現 並行,提高執行效率。python 採用 threading 和 queue 模組實現多執行緒程式設計。重量級程序,是程式的一次執行。每個程序有自己的記憶體空間 資料棧,僅能使用程序間通訊 ipc 而不能直接共享資訊。程序池的大小是每次同時執行的程序數,但是並不會影響主程序申請程序的...

高併發和多執行緒

高併發和多執行緒 總是被一起提起,給人感覺兩者好像相等,實則高併發 多執行緒 多執行緒是完成任務的一種方法,高併發是系統執行的一種狀態,通過多執行緒有助於系統承受高併發狀態的實現。高併發是一種系統執行過程中遇到的一種 短時間內遇到大量操作請求 的情況,主要發生在web系統集中大量訪問或者socket...