Pythonマルチスレッドのデッドロック現象と再帰的ロック
デッドロック現象とは何ですか?2つのスレッドが互いにリソースを解放するのを待つと、デッドロックが発生します。
といった:
from threading import Thread
from threading import Lock
import time
lock_A = Lock()
lock_B = Lock()
class MyThread(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
lock_A.acquire()
print(f"{self.name}拿到了A锁")
lock_B.acquire()
print(f"{self.name}拿到了B锁")
lock_B.release()
print(f"{self.name}释放了B锁")
lock_A.release()
print(f"{self.name}释放了A锁")
def f2(self):
lock_B.acquire()
print(f"{self.name}拿到了B锁")
time.sleep(0.1)
lock_A.acquire()
print(f"{self.name}拿到了A锁")
lock_A.release()
print(f"{self.name}释放了A锁")
lock_B.release()
print(f"{self.name}释放了B锁")
if __name__ == "__main__":
for i in range(3):
t = MyThread()
t.start()
Thread-1拿到了A锁
Thread-1拿到了B锁
Thread-1释放了B锁
Thread-1释放了A锁
Thread-1拿到了B锁
Thread-2拿到了A锁
thread1は最初にAロックを取得しましたが、この時点でt2とt3もAロックを取得したいと考えていますが、t1がAロックを解放するのを待って待機することしかできず、t1は再びBロックを取得します。この時点で、t1には2つあります。 t2はABをロックし、解放されていません。t2t3は待機を続けます。t1がロックBとAを解放すると、スレッドt2とt3はロックAをめぐって競合します。結果の分析によると、t1はBロックを取得し、t2はAを取得します。ロックすると、t1はBロックを取得しますが、t1は0.1秒スリープし、t1はBロックを所有してAロックを必要とし、t2はAロックを所有してBロックを必要とします。これにより、デッドロック現象が発生します。
再帰的ロックはデッドロック現象を解決できます。ビジネスで複数のロックが必要な場合は、最初に再帰的ロックを検討してください。
from threading import Thread
from threading import RLock
import time
lock_A = lock_B = RLock() # 必须这样写
# 这样写不行
# lock_A = RLock
# lock_B = lock_A
# 递归锁有一个计数的功能:原数字为0,上一次锁,计数+1,释放一次锁,计数-1
# 只要递归锁上面的数字不为0,其他线程就不能抢锁
class MyThread(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
lock_A.acquire()
print(f"{self.name}拿到了A锁")
lock_B.acquire()
print(f"{self.name}拿到了B锁")
lock_B.release()
print(f"{self.name}释放了B锁")
lock_A.release()
print(f"{self.name}释放了A锁")
def f2(self):
lock_B.acquire()
print(f"{self.name}拿到了B锁")
time.sleep(0.1)
lock_A.acquire()
print(f"{self.name}拿到了A锁")
lock_A.release()
print(f"{self.name}释放了A锁")
lock_B.release()
print(f"{self.name}释放了B锁")
if __name__ == "__main__":
for i in range(3):
t = MyThread()
t.start()
Thread-1拿到了A锁
Thread-1拿到了B锁
Thread-1释放了B锁
Thread-1释放了A锁
Thread-1拿到了B锁
Thread-1拿到了A锁
Thread-1释放了A锁
Thread-1释放了B锁
Thread-2拿到了A锁
Thread-2拿到了B锁
Thread-2释放了B锁
Thread-2释放了A锁
Thread-2拿到了B锁
Thread-2拿到了A锁
Thread-2释放了A锁
Thread-2释放了B锁
Thread-3拿到了A锁
Thread-3拿到了B锁
Thread-3释放了B锁
Thread-3释放了A锁
Thread-3拿到了B锁
Thread-3拿到了A锁
Thread-3释放了A锁
Thread-3释放了B锁
Process finished with exit code 0