gitclone 一个tag的地址_一个无锁队列和FreeList实现
代碼實(shí)現(xiàn)了這篇文章中的無鎖隊(duì)列。
fangcun:簡單,高效,實(shí)用的非阻塞(無鎖)和阻塞并行隊(duì)列算法?zhuanlan.zhihu.com無鎖隊(duì)列需要實(shí)現(xiàn)一個(gè)FreeList來避免一個(gè)線程釋放了結(jié)點(diǎn),而另一個(gè)線程仍在訪問該結(jié)點(diǎn)的問題,如圖所示的語句就存在這個(gè)問題:
代碼使用mingw64在windows下成功編譯,使用gcc內(nèi)建的原子操作函數(shù)。
且實(shí)現(xiàn)代碼入隊(duì)和出隊(duì)操作的每條語句依賴前一語句,編譯器不會(huì)進(jìn)行語句級(jí)的重排。
FreeList使用了一個(gè)技巧來使FreeList的結(jié)點(diǎn)和無鎖隊(duì)列的結(jié)點(diǎn)使用完全相同的內(nèi)存,這樣結(jié)點(diǎn)不是在FreeList中,就是在無鎖隊(duì)列中,不會(huì)出現(xiàn)泄漏問題。
FreeList的Alloc(給無鎖隊(duì)列分配結(jié)點(diǎn))和Free操作(這個(gè)Free操作是給無鎖隊(duì)列用來將結(jié)點(diǎn)放入FreeList中)也是無鎖的。
FreeList自身的釋放結(jié)點(diǎn)操作需要在安全的地方(非競爭環(huán)境)進(jìn)行。
FreeList的最大結(jié)點(diǎn)數(shù)等于無鎖隊(duì)列中元素最多時(shí)的元素個(gè)數(shù)。
無鎖隊(duì)列中的元素個(gè)數(shù)沒有限制,這里的FreeList的最大結(jié)點(diǎn)數(shù)不是指FreeList存在大小限制,而是指無鎖隊(duì)列中Free的元素會(huì)被放進(jìn)FreeList重復(fù)使用,所以FreeList的最大結(jié)點(diǎn)數(shù)不可能超過無鎖隊(duì)列的峰值元素?cái)?shù)。
無鎖隊(duì)列中的結(jié)點(diǎn)可以安全地放入FreeList中重復(fù)使用,即使存在多個(gè)線程持有結(jié)點(diǎn)嘗試出隊(duì)結(jié)點(diǎn),也只有一個(gè)可以成功出隊(duì),也就是結(jié)點(diǎn)只被放入FreeList一次,不會(huì)被其它線程再次放入,放入FreeList的結(jié)點(diǎn),可能仍然被其它線程持有,但它接下來的CAS會(huì)失敗,但我們不能直接釋放結(jié)點(diǎn)內(nèi)存,可以對(duì)結(jié)點(diǎn)進(jìn)行寫操作,其它線程雖然持有結(jié)點(diǎn),但只進(jìn)行讀操作,如果我們直接釋放結(jié)點(diǎn)內(nèi)存,其它線程的讀操作就會(huì)crash整個(gè)程序(讀的內(nèi)存地址非法),這也是使用FreeList的原因,其它線程持有結(jié)點(diǎn),也不影響FreeList分配它給無鎖隊(duì)列重新使用。
使用__ATOMIC_RELAXED內(nèi)存順序的原因是查閱Intel64文檔,文檔表明load,store可以在一定程度上保證線程間的內(nèi)存可見性。
__ATOMIC_RELAXED內(nèi)存順序的_atomic_load只是一個(gè)原子操作,不會(huì)作為編譯器優(yōu)化屏障。
文檔地址:
http://120.52.51.18/www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdf?120.52.51.18下面是我實(shí)現(xiàn)的無鎖隊(duì)列代碼,歡迎大家討論。
/*總結(jié)
以上是生活随笔為你收集整理的gitclone 一个tag的地址_一个无锁队列和FreeList实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vba fso读utf 文本_利用FSO
- 下一篇: unity片元着色器中获取屏幕坐标_Un