Atitit。Cas機制 軟體開發 編程語言 無鎖機制 java c# php 1. 為什麼需要無鎖操作1 2. 硬體支持 cas atomic2 3. 無鎖編程(Lock-Free)就是在某些應用場景和領域下解決以上基於鎖機制的併發編程的一種方案。3 4. Volatile 記憶體屏障(Memory ...
Atitit。Cas機制 軟體開發 編程語言 無鎖機制 java c# php
3. 無鎖編程(Lock-Free)就是在某些應用場景和領域下解決以上基於鎖機制的併發編程的一種方案。3
4. Volatile 記憶體屏障(Memory Barriers),就是它讓一個處理器內的記憶體狀態對其他處理器可見。 3
1. 為什麼需要無鎖操作
在某些時刻,你給這個變數賦一個64位的值。
1 2 3 4 |
void storeValue() { sharedValue = 0x100000002; } |
當你在32位的x86環境下使用GCC來編譯這個函數時,將會生成如下機器碼。
1 2 3 4 5 6 7 |
$ gcc -O2 -S -masm=intel test.c $ cat test.s ... mov DWORD PTR sharedValue, 2 mov DWORD PTR sharedValue+4, 1 ret ... |
這個時候你就會看到,編譯器會使用兩個單獨的機器指令來完成這個64位的賦值。第一條指令設置低32位的0×00000002,第二條指令設置高32位的0×00000001.非常明顯,這個賦值操作是非原子的。如果共用變數同時被不同的線程存取,就會出現很多錯誤:
作者:: ★(attilax)>>> 綽號:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿爾 拉帕努伊 ) 漢字名:艾龍, EMAIL:[email protected]
轉載請註明來源: http://www.cnblogs.com/attilax/
同時讀取sharedValue會帶給它一系列的問題:
1 2 3 4 5 6 7 8 9 10 11 12 |
uint64_t loadValue() { return sharedValue; }
$ gcc -O2 -S -masm=intel test.c $ cat test.s ... mov eax, DWORD PTR sharedValue mov edx, DWORD PTR sharedValue+4 ret ... |
這裡也一樣,編譯器會使用兩條機器指令來執行這個載入操作:第一條讀取低32位到eax,第二條讀取高32位到edx。在這種情況下,如果對於sharedValue進行同時存儲則會發現,它將導致一個讀撕裂——即使這個同時存儲是原子的。
眾所周知,在x86環境下,如果記憶體操作數是自然對齊的,那麼一個32位的mov指令就是原子的,但如果不是自然對齊,那麼將是非原子的。換句話說,原子性的保證僅僅是當一個32位整數的地址正好是4的倍數的時候。
2. 硬體支持 cas atomic
原子性不可能由軟體單獨保證--必須需要硬體的支持,因此是和架構相關的。在x86 平臺上,CPU提供了在指令執行期間對匯流排加鎖的手段。CPU晶元上有一條引線#HLOCK pin,如果彙編語言的程式中在一條指令前面加上首碼"LOCK",經過彙編以後的機器代碼就使CPU在執行這條指令的時候把#HLOCK pin的電位拉低,持續到這條指令結束時放開,從而把匯流排鎖住,這樣同一匯流排上別的CPU就暫時不能通過匯流排訪問記憶體了,保證了這條指令在多處理器環境中的原子性。
軟體級的原子操作,包括兩大類系統調用,一類是基於對整數進行操作的atomic_set/and/inc,一類是針對單獨的位進行操作的set/clear/change_bit,它們大部分都是基於硬體層面的CAS的指令實現的。
各種開發語言中(c,c++,java)基於操作系統提供的介面也都封裝實現了對應的原子操作api,所以開發者完全可以直接調用各個開發語言提供的介面實現無鎖程式。
3. 無鎖編程(Lock-Free)就是在某些應用場景和領域下解決以上基於鎖機制的併發編程的一種方案。
4. Volatile 記憶體屏障(Memory Barriers),就是它讓一個處理器內的記憶體狀態對其他處理器可見。
volatile
用volatile修飾的變數,線程在每次使用變數的時候,都會讀取變數修改後的最的值。volatile很容易被誤用,用來進行原子性操作
5. 參考
原子操作 vs 非原子操作 - 博客 - 伯樂線上.htm
記憶體屏障(Memory Barriers) - 博客 - 伯樂線上.htm
【原創】無鎖編程技術及實現-黑夜路人-微頭條(wtoutiao.com).htm
java中volatile關鍵字的含義 - God Is Coder - 博客園.htm