亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

用 Python 實(shí)現(xiàn)讀寫鎖

系統(tǒng) 1623 0

用 Python 實(shí)現(xiàn)讀寫鎖_第1張圖片

?

作者:weapon,閑來笑浮生懸筆一卷入毫端,朱紱臨身可與言者不過二三。

博客: zhihu.com/people/hong-wei-peng

起步

Python 提供的多線程模型中并沒有提供讀寫鎖,讀寫鎖相對(duì)于單純的互斥鎖,適用性更高,可以多個(gè)線程同時(shí)占用讀模式的讀寫鎖,但是只能一個(gè)線程占用寫模式的讀寫鎖。

通俗點(diǎn)說就是當(dāng)沒有寫鎖時(shí),就可以加讀鎖且任意線程可以同時(shí)加;而寫鎖只能有一個(gè)線程,且必須在沒有讀鎖時(shí)才能加上。

簡(jiǎn)單的實(shí)現(xiàn)

              
            

這是讀寫鎖的一個(gè)簡(jiǎn)單的實(shí)現(xiàn), self.read_num ?用來保存獲得讀鎖的線程數(shù),這個(gè)屬性屬于臨界區(qū),對(duì)其操作也要加鎖,所以這里需要一個(gè)保護(hù)內(nèi)部數(shù)據(jù)的額外的鎖? self._extra ?。

但是這個(gè)鎖是不公平的。理想情況下,線程獲得所的機(jī)會(huì)應(yīng)該是一樣的,不管線程是讀操作還是寫操作。而從上述代碼可以看到,讀請(qǐng)求都會(huì)立即設(shè)置? self.read_num += 1 ,不管有沒有獲得鎖,而寫請(qǐng)求想要獲得鎖還得等待? read_num 為 0 。

所以這個(gè)就造成了只有鎖沒有被占用或者沒有讀請(qǐng)求時(shí),可以獲得寫權(quán)限。我們應(yīng)該想辦法避免讀模式鎖長(zhǎng)期占用。

讀寫鎖的優(yōu)先級(jí)

讀寫鎖也有分 讀優(yōu)先 和 寫優(yōu)先。上面的代碼就屬于讀優(yōu)先。

如果要改成寫優(yōu)先,那就換成去記錄寫線程的引用計(jì)數(shù),讀和寫在同時(shí)競(jìng)爭(zhēng)時(shí),可以讓寫線程增加寫的計(jì)數(shù),這樣可使讀線程的讀鎖一直獲取不到, 因?yàn)樽x線程要先判斷寫的引用計(jì)數(shù),若不為0,則等待其為 0,然后進(jìn)行讀。這部分代碼不羅列了。

但這樣顯然不夠靈活。我們不需要兩個(gè)相似的讀寫鎖類。我們希望重構(gòu)我們代碼,使它更強(qiáng)大。

改進(jìn)

為了能夠滿足自定義優(yōu)先級(jí)的讀寫鎖,要記錄等待的讀寫線程數(shù),并且需要兩個(gè)條件 threading.Condition ?用來處理哪方優(yōu)先的通知。計(jì)數(shù)引用可以擴(kuò)大語義:正數(shù):表示正在讀操作的線程數(shù),負(fù)數(shù):表示正在寫操作的線程數(shù)(最多-1)

在獲取讀操作時(shí),先然后判斷時(shí)候有等待的寫線程,沒有,進(jìn)行讀操作,有,則等待讀的計(jì)數(shù)加 1 后等待? Condition ?通知;等待讀的計(jì)數(shù)減 1,計(jì)數(shù)引用加 1,繼續(xù)讀操作,若條件不成立,循環(huán)等待;

在獲取寫操作時(shí),若鎖沒有被占用,引用計(jì)數(shù)減 1,若被占用,等待寫線程數(shù)加 1,等待寫條件? Condition ?的通知。

讀模式和寫模式的釋放都是一樣,需要根據(jù)判斷去通知對(duì)應(yīng)的? Condition

              
                
                  
                    class
                  
                  ?
                  
                    RWLock
                  
                  (
                  
                    object
                  
                  ):
                
                
???? def ? __init__( self ) :
???????? self .lock?=?threading.Lock()
???????? self .rcond?=?threading.Condition( self .lock)
???????? self .wcond?=?threading.Condition( self .lock)
???????? self .read_waiter?=? 0 ???? #?等待獲取讀鎖的線程數(shù)
???????? self .write_waiter?=? 0 ??? #?等待獲取寫鎖的線程數(shù)
???????? self .state?=? 0 ?????????? #?正數(shù):表示正在讀操作的線程數(shù)???負(fù)數(shù):表示正在寫操作的線程數(shù)(最多-1)
???????? self .owners?=?[]???????? #?正在操作的線程id集合
???????? self .write_first?=?True? #?默認(rèn)寫優(yōu)先,F(xiàn)alse表示讀優(yōu)先

???? def ? write_acquire( self ,?blocking=True) :
???????? #?獲取寫鎖只有當(dāng)
????????me?=?threading.get_ident()
????????with? self . lock:
???????????? while ? not ? self ._write_acquire(me):
???????????????? if ? not ? blocking:
???????????????????? return ?False
???????????????? self .write_waiter?+=? 1
???????????????? self .wcond.wait()
???????????????? self .write_waiter?-=? 1
???????? return ?True

???? def ? _write_acquire( self ,?me) :
???????? #?獲取寫鎖只有當(dāng)鎖沒人占用,或者當(dāng)前線程已經(jīng)占用
???????? if ? self .state?==? 0 ? or ?( self .state?<? 0 ? and ?me? in ? self .owners):
???????????? self .state?-=? 1
???????????? self .owners.append(me)
???????????? return ?True
???????? if ? self .state?>? 0 ? and ?me? in ? self . owners:
????????????raise?RuntimeError( 'cannot?recursively?wrlock?a?rdlocked?lock' )
???????? return ?False

???? def ? read_acquire( self ,?blocking=True) :
????????me?=?threading.get_ident()
????????with? self . lock:
???????????? while ? not ? self ._read_acquire(me):
???????????????? if ? not ? blocking:
???????????????????? return ?False
???????????????? self .read_waiter?+=? 1
???????????????? self .rcond.wait()
???????????????? self .read_waiter?-=? 1
???????? return ?True

???? def ? _read_acquire( self ,?me) :
???????? if ? self .state?<? 0 :
???????????? #?如果鎖被寫鎖占用
???????????? return ?False

???????? if ? not ? self . write_waiter:
????????????ok?=?True
???????? else:
????????????ok?=?me? in ? self .owners
???????? if ?ok? or ? not ? self . write_first:
???????????? self .state?+=? 1
???????????? self .owners.append(me)
???????????? return ?True
???????? return ?False

???? def ? unlock( self ) :
????????me?=?threading.get_ident()
????????with? self . lock:
???????????? try:
???????????????? self .owners.remove(me)
????????????except? ValueError:
????????????????raise?RuntimeError( 'cannot?release?un-acquired?lock' )

???????????? if ? self .state?>? 0 :
???????????????? self .state?-=? 1
???????????? else:
???????????????? self .state?+=? 1
???????????? if ? not ? self . state:
???????????????? if ? self .write_waiter? and ? self . write_first: ??? #?如果有寫操作在等待(默認(rèn)寫優(yōu)先)
???????????????????? self .wcond.notify()
????????????????elif? self . read_waiter:
???????????????????? self .rcond.notify_all()
????????????????elif? self . write_waiter:
???????????????????? self .wcond.notify()

????read_release?=?unlock
????write_release?=?unlock


熱 門 推 薦
用Python創(chuàng)建微信機(jī)器人

用Python機(jī)器人監(jiān)聽微信群聊

用Python獲取攝像頭并實(shí)時(shí)控制人臉

開源項(xiàng)目 | 用Python美化LeetCode倉庫

推薦Python中文社區(qū)旗下的幾個(gè)服務(wù)類公眾號(hào)
征稿啟事 | Python中文社區(qū)有獎(jiǎng)?wù)魑?

用 Python 實(shí)現(xiàn)讀寫鎖_第2張圖片

▼ 點(diǎn)擊成為 社區(qū)注冊(cè)會(huì)員? ? ? ? ?? 「在看」 一下,一起PY!


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲最大免费视频网 | 免费亚洲视频 | 国产亚洲久久 | 国产精品欧美韩国日本久久 | 日本免费一区二区三区a区 日本免费一区二区三区看片 | 天天添天天射 | 视频在线一区二区 | 福利视频网页 | 亚洲国产精品国产自在在线 | 成人啪啪免费看 | 国产亚洲一区在线 | tobesex日本护士| 久久久久四虎国产精品 | 国产在线一区在线视频 | 99re在线 | 国产亚洲精品福利在线 | 91精品国产免费网站 | 香蕉国产在线观看免费 | 国产一区 在线视频 | 免费一级成人免费观看 | 国产在线观看美女福利精 | 亚洲国产香蕉视频欧美 | 免费高h影片在线观看 | 久草在线视频资源站 | 久久精品爱国产免费久久 | 久久综合久久综合久久综合 | 69性影院在线观看国产精品87 | 日本又黄又爽又色的免费视频 | 国产一区二区三区精品久久呦 | 亚洲毛片一级带毛片基地 | 国产精品久线观看视频 | 在线亚洲一区二区 | 亚洲欧洲国产精品久久 | 老子影院午夜伦不卡 | 国产日韩欧美亚洲综合在线 | 四虎在线视频观看大全影视 | 国语毛片 | 乱色专区| 午夜噜噜噜私人影院在线播放 | 欧美一区二区在线观看视频 | 国产羞羞视频在线播放 |