亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python 中怎么實現一個讀寫鎖

發布時間:2021-07-10 14:00:48 來源:億速云 閱讀:121 作者:Leah 欄目:大數據

本篇文章給大家分享的是有關Python 中怎么實現一個讀寫鎖,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

簡單的實現

import threading
class 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:

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 中怎么實現一個讀寫鎖,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌兰浩特市| 涟水县| 桃江县| 彰化县| 镇安县| 博乐市| 乐昌市| 泽州县| 三台县| 乌拉特前旗| 石阡县| 盘山县| 万载县| 汕尾市| 两当县| 屏边| 乌拉特中旗| 长顺县| 五家渠市| 河间市| 新绛县| 扶余县| 邵阳县| 海安县| 长治县| 宁陕县| 漯河市| 牡丹江市| 西乌珠穆沁旗| 额济纳旗| 涞水县| 弥勒县| 全州县| 汾西县| 理塘县| 呼玛县| 巴青县| 历史| 定远县| 宁陕县| 湟中县|