Lock Free (無鎖併發)

CAS( compare and swap) 原子操做,保證了若是須要更新的地址沒有被其餘進程(線程)改動過,那麼它能夠安全的寫入。而這也是咱們對於某個數據或者數據結構加鎖要保護的內容,保證讀寫的一致性,不出現dirty data。可在循環中不斷執行CAS,若是共享變量沒有改變,那麼swap,在當前環境中寫入,不然繼續do-while的Retry-Loop。html

1 int compare_and_swap (int* reg, int oldval, int newval) {
2   ATOMIC();
3   int old_reg_val = *reg;
4   if (old_reg_val == oldval) 
5      *reg = newval;
6   END_ATOMIC();
7   return old_reg_val;
8 }

ABA問題最容易發生在lock free算法中的,地址被重用的狀況算法

無鎖至關於「鎖」的粒度變小了,主要是「鎖」HEAD和TAIL這兩個關鍵資源。而不是整個數據結構。
shell

無鎖與自旋鎖比較:緩存

無鎖安全

自旋鎖數據結構

自旋鎖與互斥鎖比較:併發

1. 自旋鎖不會使線程狀態發生切換,一直處於用戶態,即線程一直都是active的;不會使線程進入阻塞狀態,減小了沒必要要的上下文切換,執行速度快oop

2. 互斥鎖在獲取不到鎖的時候會進入阻塞狀態,從而進入內核態,當獲取到鎖的時候須要從內核態恢復,須要線程上下文切換。 (線程被阻塞後便進入內核(Linux)調度狀態,這個會致使系統在用戶態與內核態之間來回切換,嚴重影響鎖的性能)post

  • 自旋鎖:線程獲取鎖的時候,若是鎖被其餘線程持有,則當前線程將循環等待,直到獲取到鎖。
  • 自旋鎖等待期間,線程的狀態不會改變,線程一直是用戶態而且是活動的(active)。
  • 自旋鎖若是持有鎖的時間太長,則會致使其它等待獲取鎖的線程耗盡CPU。
  • 自旋鎖自己沒法保證公平性,同時也沒法保證可重入性。
  • 基於自旋鎖,能夠實現具有公平性和可重入性質的鎖。
  • TicketLock:採用相似銀行排號叫好的方式實現自旋鎖的公平性,可是因爲不停的讀取serviceNum,每次讀寫操做都必須在多個處理器緩存之間進行緩存同步,這會致使繁重的系統總線和內存的流量,大大下降系統總體的性能。
  • CLHLock和MCSLock經過鏈表的方式避免了減小了處理器緩存同步,極大的提升了性能,區別在於CLHLock是經過輪詢其前驅節點的狀態,而MCS則是查看當前節點的鎖狀態。
Mutex主要解決併發實體之間的互斥的問題,而semaphone主要解決併發實體之間的同步問題。針對一些臨界區比較少,處理開銷比較小,並且實時性要求比較高的場景能夠使用spin_lock來替代mutex實現互斥, 而若是須要共享的數據只有一個字段,能夠使用lock-free的方式來替代spin_lock從而達到更高的性能。
 
條件變量:
用wait和signal實現同步互斥,其中這兩個操做須要用互斥量包裹,互斥鎖+條件變量能夠實現讀寫鎖(多個讀鎖能夠進入臨界區,只有一個寫鎖進入臨界區,讀寫鎖同時只能有一種進入臨界區)

參考博客: 性能

gaochundong

coolshell

IBM developer

自旋鎖

CAS源碼解讀

相關文章
相關標籤/搜索