The deadlock phenomenon and recursive lock of python multithreading

The deadlock phenomenon and recursive lock of python multithreading

What is a deadlock phenomenon? When two threads wait for each other to release resources, a deadlock occurs.
such as:

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 first grabbed the A lock, at this time t2 and t3 also want to grab the A lock, but can only wait, waiting for t1 to release the A lock, and t1 grabs the B lock again. At this time, t1 has two locks AB and has not been released. t2 t3 continues to wait; When t1 releases locks B and A accordingly, threads t2 and t3 compete for lock A. According to the analysis of the results, t1 grabs the B lock, t2 grabs the A lock, and t1 grabs the B lock, but then t1 sleeps 0.1 Seconds, t1 owns the B lock and wants A lock, and t2 owns the A lock and wants B lock, which forms a deadlock phenomenon.

Recursive locks can solve the deadlock phenomenon. When a business needs multiple locks, first consider recursive locks:

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

Guess you like

Origin blog.csdn.net/m0_50481455/article/details/113918165