無鎖佇列的實現

2022-08-12 08:54:21 字數 858 閱讀 9719

可以用cas 以及fetch等原子操作來實現無鎖的佇列,說是無鎖其實感覺也是有鎖的,只是鎖的力度比較小,能提公升效能

bool cas(t*addr, t expected, t newvalue) 

else

return

false

; }

使用陣列來實現佇列是很常見的方法,因為沒有記憶體的分部和釋放,一切都會變得簡單,實現的思路如下:

1)陣列佇列應該是乙個ring buffer形式的陣列(環形陣列)

2)陣列的元素應該有三個可能的值:head,tail,empty(當然,還有實際的資料)

3)陣列一開始全部初始化成empty,有兩個相鄰的元素要初始化成head和tail,這代表空佇列。

4)enqueue操作。假設資料x要入佇列,定位tail的位置,使用double-cas方法把(tail, empty) 更新成 (x, tail)。需要注意,如果找不到(tail, empty),則說明佇列滿了。

5)dequeue操作。定位head的位置,把(head, x)更新成(empty, head),並把x返回。同樣需要注意,如果x是tail,則說明隊列為空。

演算法的乙個關鍵是——如何定位head或tail?

1)我們可以宣告兩個計數器,乙個用來計數enqueue的次數,乙個用來計數dequeue的次數。

2)這兩個計算器使用使用fetch&add來進行原子累加,在enqueue或dequeue完成的時候累加就好了。

3)累加後求個模什麼的就可以知道tail和head的位置了。

如下圖所示:

無鎖佇列的實現 小結

原文見 cool shell cas,即lock free的一種實現,是構成jdk concurrent包高效併發容器的重要基礎,因此認真閱讀了一下。讀後附註 對aba問題的理解 在db裡,根據一行記錄中 最後修改時間 欄位的值是否變更,作為更新該行記錄時的參照物,是平時常見的一種做法,類似樂觀鎖。...

mySQL無鎖佇列 go 無鎖佇列

無鎖佇列適用場景 兩個執行緒之間的互動資料,乙個執行緒生產資料,另外乙個執行緒消費資料,效率高 缺點 需要使用固定分配的空間,不能動態增加 減少長度,存在空間浪費和無法擴充套件空間問題 package main import fmt reflect strings time type loopque...

lockFreeQueue 無鎖佇列實現與總結

在工程上,為了解決兩個處理器互動速度不一致的問題,我們使用佇列作為快取,生產者將資料放入佇列,消費者從佇列中取出資料。這個時候就會出現四種情況,單生產者單消費者,多生產者單消費者,單生成者多消費者,多生產者多消費者。我們知道,多執行緒往往會帶來資料不一致的情況,一般需要靠加鎖解決問題。但是,加鎖往往...