电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Python讀寫鎖實現(xiàn)實現(xiàn)代碼解析

瀏覽:118日期:2022-07-04 08:56:50

起步

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

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

簡單的實現(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àn),self.read_num 用來保存獲得讀鎖的線程數(shù),這個屬性屬于臨界區(qū),對其操作也要加鎖,所以這里需要一個保護內(nèi)部數(shù)據(jù)的額外的鎖 self._extra 。

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

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

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

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

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

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

改進

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

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

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

讀模式和寫模式的釋放都是一樣,需要根據(jù)判斷去通知對應的 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ù) 負數(shù):表示正在寫操作的線程數(shù)(最多-1) self.owners = [] # 正在操作的線程id集合 self.write_first = True # 默認寫優(yōu)先,F(xiàn)alse表示讀優(yōu)先 def write_acquire(self, blocking=True): # 獲取寫鎖只有當 me = threading.get_ident() with self.lock: while not self._write_acquire(me):if not blocking: return Falseself.write_waiter += 1self.wcond.wait()self.write_waiter -= 1 return True def _write_acquire(self, me): # 獲取寫鎖只有當鎖沒人占用,或者當前線程已經(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 Falseself.read_waiter += 1self.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: # 如果有寫操作在等待(默認寫優(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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 滚筒烘干机_转筒烘干机_滚筒干燥机_转筒干燥机_回转烘干机_回转干燥机-设备生产厂家 | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 | 引领中高档酒店加盟_含舍·美素酒店品牌官网 | 东风体检车厂家_公共卫生体检车_医院体检车_移动体检车-锦沅科贸 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 变色龙云 - 打包app_原生app_在线制作平台_短链接_ip查询 | FAG轴承,苏州FAG轴承,德国FAG轴承-恩梯必传动设备(苏州)有限公司 | 课件导航网_ppt课件_课件模板_课件下载_最新课件资源分享发布平台 | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 成都网站建设制作_高端网站设计公司「做网站送优化推广」 | 北京开业庆典策划-年会活动策划公司-舞龙舞狮团大鼓表演-北京盛乾龙狮鼓乐礼仪庆典策划公司 | TMT观察网_独特视角观察TMT行业 派财经_聚焦数字经济内容服务平台 | 智能监控-安防监控-监控系统安装-弱电工程公司_成都万全电子 | 锂电池生产厂家-电动自行车航模无人机锂电池定制-世豹新能源 | 罗茨真空机组,立式无油往复真空泵,2BV水环真空泵-力侨真空科技 | 菏泽知彼网络科技有限公司 | 电销卡_北京电销卡_包月电话卡-豪付网络 | 贝朗斯动力商城(BRCPOWER.COM) - 买叉车蓄电池上贝朗斯商城,价格更超值,品质有保障! | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库-首页-东莞市傲马网络科技有限公司 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 立刷【微电签pos机】-嘉联支付立刷运营中心 | 塑料造粒机「厂家直销」-莱州鑫瑞迪机械有限公司 | 超声波清洗机_大型超声波清洗机_工业超声波清洗设备-洁盟清洗设备 | 伟秀电气有限公司-10kv高低压开关柜-高低压配电柜-中置柜-充气柜-欧式箱变-高压真空断路器厂家 | 楼梯定制_楼梯设计施工厂家_楼梯扶手安装制作-北京凌步楼梯 | 布袋除尘器-单机除尘器-脉冲除尘器-泊头市兴天环保设备有限公司 布袋除尘器|除尘器设备|除尘布袋|除尘设备_诺和环保设备 | 施工电梯_齿条货梯_烟囱电梯_物料提升机-河南大诚机械制造有限公司 | 阴离子_阳离子聚丙烯酰胺厂家_聚合氯化铝价格_水处理絮凝剂_巩义市江源净水材料有限公司 | 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 体感VRAR全息沉浸式3D投影多媒体展厅展会游戏互动-万展互动 | 餐饮小吃技术培训-火锅串串香培训「何小胖培训」_成都点石成金[官网] | 最新电影-好看的电视剧大全-朝夕电影网 | 换链神器官网-友情链接交换、购买交易于一体的站长平台 | LOGO设计_品牌设计_VI设计 - 特创易 | 废气处理设备-工业除尘器-RTO-RCO-蓄热式焚烧炉厂家-江苏天达环保设备有限公司 | 安徽千住锡膏_安徽阿尔法锡膏锡条_安徽唯特偶锡膏_卡夫特胶水-芜湖荣亮电子科技有限公司 | 美国查特CHART MVE液氮罐_查特杜瓦瓶_制造全球品质液氮罐 | 上海租车公司_上海包车_奔驰租赁_上海商务租车_上海谐焕租车 |