並發與鎖

來源:互聯網
上載者:User

並發與鎖

JUC AQS

AQS整體結構

鎖的擷取過程

  • CAS rote 迴轉數的問題

擷取失敗掛起的過程

釋放鎖喚醒等待的過程

  • 如何防止丟失喚醒

    入隊時不能“貪睡”,找可靠等待者並讓他叫醒自己,不在進而就擷取鎖,其他所有情況都告訴標記前驅別忘了叫醒自己

    這就夠了嗎,顯然還不行;滿足自己去“睡”的條件的check和“睡”顯然不是一個原子操作。在check後和“睡著”前如果條件變了就沒人叫醒

    unpark和park早就預防相關問題,猜想內部是有變數記憶了上次的操作後狀態,同時基於作業系統提供的鎖保證了原子性

  • 如何防止驚群問題

    鎖的喚醒通常是有喚醒一個等待線程和喚醒全部等待線程的;通常在編程條件下如果想減少全部喚醒的引發不必要的競爭時,還要注意虛假

    喚醒問題,被喚醒的線程如果條件不滿足條件釋放鎖後造成喚醒鏈脫節的問題。而這種情況又不能簡單在自己釋放鎖前去喚醒其他等待者。

    所以比如在leader-follower模式中,如果leader線程只在原leader線程離任時喚醒任意一個等待線程時,則當線程都在follower模式

    時因為沒有喚醒者陷入停機狀態,所以在每次完成工作時還要嘗試自薦為leader。如果leader在離任時喚起其他所有線程顯然時驚群的。

AQS小結

  • 雙檢鎖的簡單最佳化
  • 流言:cas+clh隊列語義上等價於鎖

    線程阻塞於喚醒的閉合性無法滿足,需要藉助cpu指令中的屏蔽中斷與禁止搶佔保證調度切換的原子性

從CAS到記憶體屏障再到緩衝一致性協議

  • volatile happens-before

    如果a線程先寫入新值,b線程緊接著(賦值後隔一個刻度,這樣可以使得無論是lock首碼的指令排空store buffer

    並且失效其他處理器的對於緩衝得以執行完,或者時鐘中斷引發store buffer排空進而觸發緩衝一致性同步)去讀就能

    最新值,不過由於需要間隔一個刻度,看似違反happens-before;不過由於緊接著是lock的情況在緊接著的時鐘

    周期裡由於lock觸發緩衝一致性同步會失效該資料項目的舊值所以不會有問題,時鐘中斷的間接觸發緩衝同步也類似。

  • unsafe 源碼

https://github.com/dmlloyd/openjdk/blob/jdk/jdk/src/hotspot/share/prims/unsafe.cpp

  • CAS 指令與匯流排鎖 CMPXCHG16B
  • 記憶體屏障與緩衝一致性協議
  • 編譯器最佳化、cpu亂序執行【關於體繫結構只針對X86-64其他亂序自由度更大的暫不考慮,料想其原理是類似的】

冒險:

資料冒險
結構冒險
控制冒險(分支冒險)
MESI、MOSI、MESIF

一圖勝過千言(待添加),

硬體結構: 寫緩衝的讀取優先與L1cache,寫合并WC最佳化;寫回緩衝WB,寫穿透緩衝WT,

寫失效WI,經驗表明寫失效,更節約頻寬

寫更新WU,看起來快,有時候是不必要的如果更新每個緩衝比起一條失效指令代價大許多;

更新可能是斷續多次而失效只要一次,而且緩衝行內容的大小比緩衝地址大位寬大不少

X86-64一致性高,LoadLoad Memory Barrier是因為讀屏障會強制等待Invalidate Queue清空才繼續執行,

這樣可以消除其引發的讀亂序問題

  • 緩衝一致性協議提供了緩衝一致性的必要的手段和機制,記憶體屏障是通過簡單的抑制亂序以及對這些手段和機制的利用

    進而達到緩衝一致的對外表現。這裡提現硬體的對外複雜度的隔離封裝,對外暴露了簡單的介面,內部實現像水面下的

    冰山。

緩衝一致性協議顯然在硬體上有鎖的語義的

loadload

loadstore

storeload (x86 TSO 唯一亂序的地方)

storestore

Synchronized

  • 對象頭

  • 鎖定擴大

  • 安全點及延申

    精確式GC、安全點調度以及協程調度java與golang

Futex

Futex是一種使用者態和核心態混合的同步機制。首先,同步的進程間通過mmap共用一段記憶體,futex變數就位於這段共用 的記憶體中且操作是原子的,當進程嘗試進入互斥區或者退出互斥區的時候,先去查看共用記憶體中的futex變數,如果沒有競爭發生,則只修改futex,而不 用再執行系統調用了。當通過訪問futex變數告訴進程有競爭發生,則還是得執行系統調用去完成相應的處理(wait 或者 wake up)。簡單的說,futex就是通過在使用者態的檢查,(motivation)如果瞭解到沒有競爭就不用陷入核心了,大大提高了low-contention時候的效率。 Linux從2.5.7開始支援Futex。
  • 自旋鎖

    核心的基本鎖之一

  • 自旋最佳化(jdk9與自旋提示)

自旋是在迴圈中不斷重試檢測條件變數的值,這樣為了保證可見度,就需要不斷的同步緩衝,造成很多不必要的開銷。

  • RCU鎖

    包含的資料通常都是指標類型的,每個核上都發生過調度就說明如果其他核在該rcu鎖的讀臨界區,完成一輪調度後(讀臨界區不可搶佔)

    如果再有新的線程可見的資料是新的老版本的可以釋放了。如果是可搶佔的RCU就需要在鎖定開頭和釋放的結尾維護一個計數器。

  • 屏蔽中斷與禁止搶佔

鎖的構成要素

>cas>等待隊列>屏蔽中斷禁止搶佔的原子調度內容相關的切換

理解與體會

  • 不總結不準備就會拔劍四顧心茫然

  • 讀寫時序

  • 控制流程與資料流的等價性

  • 幾種並行存取模型 actor、CSP、CPS/CallCC
  • 鎖的本質問題是時序問題,調度可以解決時序問題,調度問題從cpu角度看又是執行權的問題,鎖是保護了資料,鎖是通過限制代碼的執行來保護資料的。

mesi為什麼可以保證一致性對分布式環境緩衝一致性有什麼啟示

首先匯流排的作用是巨大的,他保證了多核乃至多路cpu間的緩衝一致性

分布式環境下由於沒有統一的匯流排,缺少收斂的協調控制。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.