天天看點

無鎖并發和無等待并發

有兩種非阻塞線程同步算法,即無鎖和無等待,這兩種算法經常會産生混淆。

無鎖并發和無等待并發

在無鎖系統中,當任何特定的運算被阻塞的時候,所有CPU可以繼續處理其他的運算。換種方式說,在無鎖系統中,當給定線程被其他線程阻塞的時候,所有CPU可以不停的繼續處理其他工作。無鎖算法大大增加系統整體的吞吐量,因為它隻偶爾會增加一定的交易延遲。大部分高端資料庫系統是基于無鎖算法而構造的,以滿足不同級别。

相反,無等待算法保證了所有CPU在連續處理有效工作的時候,沒有運算會被其他運算所阻塞。相比于無鎖算法,無等待算法有更強的保證,并且不會以交易延遲為代價,來保證高吞吐量。當然,相比之下這種算法也更難實作,測試和debug。Linux kernel的無鎖頁面緩存就是無等待系統的一個典型案例。

在某些情況下,例如系統在處理一些并發交易并且有一些輕微的延遲請求,無鎖系統是在開發難度和高并發請求的一個好的折中選擇。網站的資料庫伺服器就是一個很好的無鎖設計的例子。當任何請求交易被阻塞,同時總是有更多的交易在被處理,是以CPU永遠不會空閑。難點就是要建立一個交易排程器,來維護一個比較好的平均延遲和一定的誤差。

在某些場景下,系統擁有和cpu核心數量相似的并發交易,或者很準确的實時請求,開發者就需要花費更多的時間去建構無等待系統了。在這種案例中,例如:阻斷單一交易是不行的,因為cpu沒有其他交易可以操作,最小的吞吐量,或指定的交易需要在一個非機率化的時間段内完成。核反應控制軟體就是一個無等待系統的絕好案例。

RethinkDB是一個無鎖系統。在一台具備N個CPU核心的機器上,在大量正常負載的情況下,我們可以保證沒有任何核心會處于空閑狀态,隻要有大約N×4的并發交易,則可以保證沒有io管道容量被浪費。例如,一個8核心的系統,如果RethinkDB正在處理大概32個或更多的并發交易時,沒有任何硬體會處于空閑。如果通常隻有少于32筆的并發交易,那麼有些核心也許是浪費了。(當然如果你僅僅有32筆并發數量的話,也不需要一個8核的機器)