Python線程-死鎖


死鎖產生的4個必要條件:
    1、互斥:一個資源同一時刻只允許一個線程進行訪問。
    2、占有未釋放:一個線程占有資源,且沒有釋放資源。
    3、不可搶占:一個已經占有資源的線程無法搶占到其他線程擁有的資源。
    4、循環等待:兩個或者兩個以上的線程,本身擁有資源,不釋放資源,並且同時嘗試獲得其他線程所持有的資源,這種資源的申請關系形成一個閉環的鏈條。

死鎖的避免:

關於死鎖的避免,仁者見仁智者見智。

主要還是從造成死鎖的四個條件入手,四個條件不能滿足,就不會死鎖。

以下是我本人的一些方法:

1.線程等待時(wait)給予一個默認的等待時間

2.線程之間資源避免相互申請對方的資源,可以通過一些容器來控制並發,比如blockqueue,等等一些線程安全的容器

3.盡量避免線程在等待的同時申請資源

4.死鎖檢測,一個線程在等待一段時間后還沒有獲得資源就放棄申請。對等待時間進行檢測。

 

一個死鎖的例子:

# 線程死鎖,在classA和classB相互調用對方的方法,並且相互等待對方釋放資源


class ClassA:
    def __init__(self):
        self.lock=threading.RLock()

    # 得到classA的鎖,試圖得到classB的鎖
    def infoA(self, b):
        self.lock.acquire()
        time.sleep(10)
        b.info()
        self.lock.release()

    def info(self):
        self.lock.acquire()
        print("this is ClassA info")
        self.lock.release()


class ClassB:
    def __init__(self):
        self.lock = threading.RLock()

    # 得到classB的鎖,試圖得到classA的鎖
    def infoB(self, a):
        self.lock.acquire()
        time.sleep(10)
        a.info()
        self.lock.release()

    def info(self):
        self.lock.acquire()
        print("this is ClassB info")
        self.lock.release()


ca=ClassA()
cb=ClassB()

def funA():
    ca.infoA(cb)
def funB():
    cb.infoB(ca)

# 函數調用不是線程,不會死鎖
# funA()
# funB()

t1=threading.Thread(target=funA).start()
t2=threading.Thread(target=funB).start()

說明:

線程 狀態      
classA 獲得classA的鎖,sleep(classA的鎖未釋放) 申請classB的鎖 死鎖  
classB 獲得classB的鎖,sleep(classB的鎖未釋放) 申請classA的鎖 死鎖  
         


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM