起步
Python 提供的多線程模型中并沒(méi)有提供讀寫(xiě)鎖,讀寫(xiě)鎖相對(duì)于單純的互斥鎖,適用性更高,可以多個(gè)線程同時(shí)占用讀模式的讀寫(xiě)鎖,但是只能一個(gè)線程占用寫(xiě)模式的讀寫(xiě)鎖。
通俗點(diǎn)說(shuō)就是當(dāng)沒(méi)有寫(xiě)鎖時(shí),就可以加讀鎖且任意線程可以同時(shí)加;而寫(xiě)鎖只能有一個(gè)線程,且必須在沒(méi)有讀鎖時(shí)才能加上。
簡(jiǎn)單的實(shí)現(xiàn)
import threadingclass RWlock(object): def __init__(self): self._lock = threading.Lock() self._extra = threading.Lock() self.read_num = 0 def read_acquire(self): with self._extra: self.read_num += 1 if self.read_num == 1: self._lock.acquire() def read_release(self): with self._extra: self.read_num -= 1 if self.read_num == 0: self._lock.release() def write_acquire(self): self._lock.acquire() def write_release(self): self._lock.release()
這是讀寫(xiě)鎖的一個(gè)簡(jiǎn)單的實(shí)現(xiàn),self.read_num 用來(lái)保存獲得讀鎖的線程數(shù),這個(gè)屬性屬于臨界區(qū),對(duì)其操作也要加鎖,所以這里需要一個(gè)保護(hù)內(nèi)部數(shù)據(jù)的額外的鎖 self._extra 。
但是這個(gè)鎖是不公平的。理想情況下,線程獲得所的機(jī)會(huì)應(yīng)該是一樣的,不管線程是讀操作還是寫(xiě)操作。而從上述代碼可以看到,讀請(qǐng)求都會(huì)立即設(shè)置 self.read_num += 1,不管有沒(méi)有獲得鎖,而寫(xiě)請(qǐng)求想要獲得鎖還得等待 read_num 為 0 。
所以這個(gè)就造成了只有鎖沒(méi)有被占用或者沒(méi)有讀請(qǐng)求時(shí),可以獲得寫(xiě)權(quán)限。我們應(yīng)該想辦法避免讀模式鎖長(zhǎng)期占用。
讀寫(xiě)鎖的優(yōu)先級(jí)
讀寫(xiě)鎖也有分 讀優(yōu)先 和 寫(xiě)優(yōu)先。上面的代碼就屬于讀優(yōu)先。
如果要改成寫(xiě)優(yōu)先,那就換成去記錄寫(xiě)線程的引用計(jì)數(shù),讀和寫(xiě)在同時(shí)競(jìng)爭(zhēng)時(shí),可以讓寫(xiě)線程增加寫(xiě)的計(jì)數(shù),這樣可使讀線程的讀鎖一直獲取不到, 因?yàn)樽x線程要先判斷寫(xiě)的引用計(jì)數(shù),若不為0,則等待其為 0,然后進(jìn)行讀。這部分代碼不羅列了。
但這樣顯然不夠靈活。我們不需要兩個(gè)相似的讀寫(xiě)鎖類(lèi)。我們希望重構(gòu)我們代碼,使它更強(qiáng)大。
改進(jìn)
為了能夠滿(mǎn)足自定義優(yōu)先級(jí)的讀寫(xiě)鎖,要記錄等待的讀寫(xiě)線程數(shù),并且需要兩個(gè)條件 threading.Condition 用來(lái)處理哪方優(yōu)先的通知。計(jì)數(shù)引用可以擴(kuò)大語(yǔ)義:正數(shù):表示正在讀操作的線程數(shù),負(fù)數(shù):表示正在寫(xiě)操作的線程數(shù)(最多-1)
在獲取讀操作時(shí),先然后判斷時(shí)候有等待的寫(xiě)線程,沒(méi)有,進(jìn)行讀操作,有,則等待讀的計(jì)數(shù)加 1 后等待 Condition 通知;等待讀的計(jì)數(shù)減 1,計(jì)數(shù)引用加 1,繼續(xù)讀操作,若條件不成立,循環(huán)等待;
在獲取寫(xiě)操作時(shí),若鎖沒(méi)有被占用,引用計(jì)數(shù)減 1,若被占用,等待寫(xiě)線程數(shù)加 1,等待寫(xiě)條件 Condition 的通知。
讀模式和寫(xiě)模式的釋放都是一樣,需要根據(jù)判斷去通知對(duì)應(yīng)的 Condition:
新聞熱點(diǎn)
疑難解答
圖片精選