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

用 Python 實現讀寫鎖

系統 1806 0

用 Python 實現讀寫鎖_第1張圖片

?

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

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

起步

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

通俗點說就是當沒有寫鎖時,就可以加讀鎖且任意線程可以同時加;而寫鎖只能有一個線程,且必須在沒有讀鎖時才能加上。

簡單的實現

              
            

這是讀寫鎖的一個簡單的實現, self.read_num ?用來保存獲得讀鎖的線程數,這個屬性屬于臨界區,對其操作也要加鎖,所以這里需要一個保護內部數據的額外的鎖? self._extra ?。

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

所以這個就造成了只有鎖沒有被占用或者沒有讀請求時,可以獲得寫權限。我們應該想辦法避免讀模式鎖長期占用。

讀寫鎖的優先級

讀寫鎖也有分 讀優先 和 寫優先。上面的代碼就屬于讀優先。

如果要改成寫優先,那就換成去記錄寫線程的引用計數,讀和寫在同時競爭時,可以讓寫線程增加寫的計數,這樣可使讀線程的讀鎖一直獲取不到, 因為讀線程要先判斷寫的引用計數,若不為0,則等待其為 0,然后進行讀。這部分代碼不羅列了。

但這樣顯然不夠靈活。我們不需要兩個相似的讀寫鎖類。我們希望重構我們代碼,使它更強大。

改進

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

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

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

讀模式和寫模式的釋放都是一樣,需要根據判斷去通知對應的? 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 ???? #?等待獲取讀鎖的線程數
???????? self .write_waiter?=? 0 ??? #?等待獲取寫鎖的線程數
???????? self .state?=? 0 ?????????? #?正數:表示正在讀操作的線程數???負數:表示正在寫操作的線程數(最多-1)
???????? self .owners?=?[]???????? #?正在操作的線程id集合
???????? self .write_first?=?True? #?默認寫優先,False表示讀優先

???? def ? write_acquire( self ,?blocking=True) :
???????? #?獲取寫鎖只有當
????????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) :
???????? #?獲取寫鎖只有當鎖沒人占用,或者當前線程已經占用
???????? 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: ??? #?如果有寫操作在等待(默認寫優先)
???????????????????? 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創建微信機器人

用Python機器人監聽微信群聊

用Python獲取攝像頭并實時控制人臉

開源項目 | 用Python美化LeetCode倉庫

推薦Python中文社區旗下的幾個服務類公眾號
征稿啟事 | Python中文社區有獎征文

用 Python 實現讀寫鎖_第2張圖片

▼ 點擊成為 社區注冊會員? ? ? ? ?? 「在看」 一下,一起PY!


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲精品亚洲人成在线播放 | 激情国产视频 | 羞羞视频网页 | 日本欧美成人 | 在线播放人成午夜免费视频 | 国产午夜精品一区二区 | 国产大尺度视频 | 亚洲国产欧洲综合997久久 | 免费一级特黄3大片视频 | 91国自产精品中文字幕亚洲 | 毛片爱做的片 | 色综合精品久久久久久久 | 国产自产拍精品视频免费看 | 欧美aav| 国产综合图区 | 羞羞视频免费在线观看 | 99久久www免费人成精品 | 精品国产精品a | 人人爱天天做夜夜爽毛片 | 操综合 | 九九99re在线视频精品免费 | 国产精品香蕉成人网在线观看 | 888米奇四色极速在线观看 | 国产香蕉视频 | 久久久久久久亚洲精品 | 精品在线免费视频 | 香蕉精品高清在线观看视频 | 老司机午夜精品视频你懂的 | www久久久久 | 中文欧美日韩 | 停停色 | 久久视频国产 | 国产性做久久久久久 | 亚洲欧美精品久久 | 亚洲免费中文字幕 | 欧美曰韩免费视频一区 | 欧美特级毛片aaaa | 99热在线免费播放 | 国产51自产区| 日本在线不卡免费 | 一级黄色录像免费观看 |