国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

用Python實現讀寫鎖的示例代碼

2020-02-15 23:31:09
字體:
來源:轉載
供稿:網友

起步

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

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

簡單的實現

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()

這是讀寫鎖的一個簡單的實現,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:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绥滨县| 平潭县| 溆浦县| 靖边县| 南木林县| 光泽县| 三门县| 彭山县| 土默特左旗| 舞钢市| 曲松县| 石嘴山市| 宣汉县| 娄底市| 武夷山市| 县级市| 翼城县| 容城县| 靖远县| 巴林左旗| 屏山县| 沾化县| 厦门市| 柘城县| 万全县| 交口县| 托克托县| 宜阳县| 桃源县| 西吉县| 巍山| 贡嘎县| 龙川县| 德保县| 尼木县| 海盐县| 凯里市| 张掖市| 遂川县| 高淳县| 安远县|