5.7. 加鎖的各種選擇

2018-02-24 15:49 更新

5.7.?加鎖的各種選擇

Linux 內(nèi)核提供了不少有力的加鎖原語能夠用來使內(nèi)核避免被自己絆倒. 但是, 如同我們已見到的, 一個(gè)加鎖機(jī)制的設(shè)計(jì)和實(shí)現(xiàn)不是沒有缺陷. 常常對(duì)于旗標(biāo)和自旋鎖沒有選擇; 它們可能是唯一的方法來正確地完成工作. 然而, 有些情況, 可以建立原子的存取而不用完整的加鎖. 本節(jié)看一下做事情的其他方法.

5.7.1.?不加鎖算法

有時(shí), 你可以重新打造你的算法來完全避免加鎖的需要. 許多讀者/寫者情況 -- 如果只有一個(gè)寫者 -- 常常能夠在這個(gè)方式下工作. 如果寫者小心使數(shù)據(jù)結(jié)構(gòu)的視圖, 由讀者所見的, 是一直一致的, 有可能創(chuàng)建一個(gè)不加鎖的數(shù)據(jù)結(jié)構(gòu).

常常可以對(duì)無鎖的生產(chǎn)者/消費(fèi)者任務(wù)有用的數(shù)據(jù)結(jié)構(gòu)是環(huán)形緩存. 這個(gè)算法包含一個(gè)生產(chǎn)者安放數(shù)據(jù)到一個(gè)數(shù)組的尾端, 而消費(fèi)者從另一端移走數(shù)據(jù). 當(dāng)?shù)竭_(dá)數(shù)組末端, 生產(chǎn)者繞回到開始. 因此一個(gè)環(huán)形緩存需要一個(gè)數(shù)組和 2 個(gè)索引值來跟蹤下一個(gè)新值放到哪里, 以及哪個(gè)值在下一次應(yīng)當(dāng)從緩存中移走.

當(dāng)小心地實(shí)現(xiàn)了, 一個(gè)環(huán)形緩存在沒有多個(gè)生產(chǎn)者或消費(fèi)者時(shí)不需要加鎖. 生產(chǎn)者是唯一允許修改寫索引和它所指向的數(shù)組位置的線程. 只要寫者在更新寫索引之前存儲(chǔ)一個(gè)新值到緩存中, 讀者將一直看到一個(gè)一致的視圖. 讀者, 輪換地, 是唯一存取讀索引和它指向的值的線程. 加一點(diǎn)小心到確保 2 個(gè)指針不相互覆蓋, 生產(chǎn)者和消費(fèi)者可以并發(fā)存取緩存而沒有競(jìng)爭(zhēng)情況.

環(huán)形緩沖展示了在幾個(gè)填充狀態(tài)的環(huán)形緩存. 這個(gè)緩存被定義成一個(gè)空情況由讀寫指針相同來指示, 而滿情況發(fā)生在寫指針緊跟在讀指針后面的時(shí)候(小心解決繞回!). 當(dāng)小心地編程, 這個(gè)緩存能夠不必加鎖地使用.

圖?5.1.?環(huán)形緩沖

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)