1. 程式人生 > >5.1.17 死鎖與死鎖的解決(遞歸鎖)

5.1.17 死鎖與死鎖的解決(遞歸鎖)

pri XA self. TE AR 圖片 解決 OS eas

1. 排斥鎖可能會造成死鎖,先看看死鎖的現象

from threading import Thread,Lock
import time

mutexA=Lock()
mutexB=Lock()

class MyThread(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print(%s 拿到了A鎖 %self.name)

        mutexB.acquire()
        print(
%s 拿到了B鎖 %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print(%s 拿到了B鎖 % self.name) time.sleep(0.1) mutexA.acquire() print(%s 拿到了A鎖 % self.name) mutexA.release() mutexB.release() if __name__
== __main__: for i in range(10): t=MyThread() t.start()

運行結果:

技術分享圖片
Thread-1 拿到了A鎖
Thread-1 拿到了B鎖
Thread-1 拿到了B鎖
Thread-2 拿到了A鎖
卡住了。。。。。。
View Code

2. 互斥鎖Lock,只能acquire()一次, 遞歸鎖RLock可以acquire()多次

# 互斥鎖只能acquire一次
from threading import Thread
from threading import Lock

mutexA=Lock()

mutexA.acquire()
print(1) mutexA.acquire() print(2) mutexA.release() 運行結果: 1 #輸出1後卡在第二個mutexA.acquire()上

# 遞歸鎖可以acquire多次
from threading import Thread,Lock
from threading import RLock

mutexA=RLock()

mutexA.acquire()
mutexA.acquire()
mutexA.release()

正常運行!

3. 遞歸鎖的應用

# 遞歸鎖:可以連續acquire多次,每acquire一次計數器+1,只有計數為0時,才能被搶到acquire
from threading import Thread,RLock
import time

mutexB=mutexA=RLock()

class MyThread(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print(%s 拿到了A鎖 %self.name)

        mutexB.acquire()
        print(%s 拿到了B鎖 %self.name)
        mutexB.release()

        mutexA.release()


    def f2(self):
        mutexB.acquire()
        print(%s 拿到了B鎖 % self.name)
        time.sleep(7)

        mutexA.acquire()
        print(%s 拿到了A鎖 % self.name)
        mutexA.release()

        mutexB.release()

if __name__ == __main__:
    for i in range(10):
        t=MyThread()
        t.start()

5.1.17 死鎖與死鎖的解決(遞歸鎖)