1. 程式人生 > >Disruptor無鎖佇列淺析

Disruptor無鎖佇列淺析

    近期在看作業系統相關資料的時候,閱讀到“訊號量與PV操作”,主要分三塊:互斥控制,同步控制,生產者與消費者問題。因為我日常與伺服器及訊息佇列打交道較多,對生產者與消費者問題比較感興趣,正好之前曾經研究過“Disruptor無鎖佇列”的實現原理,正好再結合PV操作重新回顧下:

    注:PV操作中P為荷蘭文passeren的縮寫,意思是通過。V為荷蘭文vrijgeven的縮寫,意思是釋放。

    首先解釋下Disruptor到底是什麼。Disruptor是提供了一種執行緒之間資料高速交換方式,其首先用在LMAX架構中,LMAX是金融交易所平臺,訊息吞吐量十分巨大。可以充分證明這種訊息佇列實現的高效和穩定。

    正常情況下,譬如兩個執行緒同時要訪問並修改一個訊息佇列,需要通過PV操作處理緩衝區的互斥控制和訊息接受和分發的同步控制。比如互斥控制,形象點比喻就是,有兩個小朋友,同時都想玩一個玩具,需要有一箇中間人判斷先給誰後給誰,比如說老師。多個執行緒訪問一個數據,多了一個判定過程,當訪問頻繁時,整體效能將急劇降低。


    Disruptor是如何解決問題的呢?Disruptor根本不用鎖,取而代之是確保操作執行緒是安全的。還是上面的例子,不再需要老師去裁判玩具歸屬,一個孩子玩的時候可用用一種機制保證其他孩子肯定不會搶這個玩具。


    具體實現方式是,在需要確保執行緒安全的時候,不再使用鎖,改用CAS(Compare And Swap/Set)操作。CAS的功能簡單來描述就是,當發現想改變的值已經改變,則操作失敗。類比孩子玩具的例子,當一個孩子想玩時候,發行玩具在別人手上,不用去問老師了,不再嘗試去拿玩具。

    CAS操作的資源會比鎖資源少多了,顯而易見,不需要再通過鎖方式,控制多個執行緒訪問。類比孩子玩具的例子,不再需要老師的參與了,玩玩具的孩子也不用停下來解釋。

    Disruptor具體的實現是基於CAS操作的RingBuffer環形佇列,如下圖所示,RingBuffer中分離了讀指標和寫指標,從而使生產者和消費者互不干擾,兩者可以完全併發執行,從而使效能達到數倍於傳統基於互斥鎖方式實現的訊息佇列模型。

    Disruptor實現現已經開源(Apache-2.0 license),可以git clone https://github.com/LMAX-Exchange/disruptor

。具體原始碼實現,篇幅有限,打算後面專門做一個系列來分析學習。