死锁和递归锁

(一)死锁

(1)介绍

  • 死锁是两个或多个进程,在执行过程中,因争夺资源而造成了互相等待的一种现象
  • 即两个或多个进程蚩尤各自的锁并试图获取对方持有的锁,从而导致被阻塞,不能向前执行。最终形成僵局
  • 在这种情况下,系统资源利用率极低,系统处于一种死循环状态

(2)示例

from threading import Thread, Lock
import time

metexA = Lock()
metexB = Lock()


# 类只要加括号多次 产生的肯定不同的对象
# 如果你想要实现多次加括号等到的是相同的对象 - 单例模式

class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        metexA.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        metexB.acquire()
        print(f'{self.name} 抢到了B锁')
        metexB.release()
        metexA.release()

    def func2(self):
        metexB.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了B锁')
        time.sleep(2)
        metexA.acquire()
        print(f'{self.name} 抢到了A锁')
        metexA.release()
        metexB.release()


def main():
    for i in range(10):
        t = MyThread()
        t.start()


if __name__ == '__main__':
    main()

# Thread-1 抢到了A锁
# Thread-1 抢到了B锁
# Thread-1 抢到了B锁
# Thread-2 抢到了A锁
# 线程卡死
# 开启线程后,第一个线程走到IO后,抢A,结果第二个线程已经拿到A锁了,导致卡死

(二)递归锁

(1)介绍

  • 递归锁(可重入锁)是一种特殊的锁,它允许一个线程多次请求同一个锁,称为递归地请求锁
  • 在该线程释放锁之前,会对锁计数器进行累加操作,线程每成功获得一次锁时,都要进行相应的解锁操作,直到锁计数器清零才能完全释放该锁。
  • 递归锁能够保证同一线程在持有锁时能够再次获取该锁,而不被自己所持有的锁所阻塞,从而避免死锁的发生。
  • 但是注意要正常使用递归锁,避免过多地获取锁导致性能下降。

(2)示例

from threading import Thread, Lock, RLock
import time

# 两个变量同时指向一把锁
metexA = metexB = RLock()


# 类只要加括号多次 产生的肯定不同的对象
# 如果你想要实现多次加括号等到的是相同的对象 - 单例模式

class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        metexA.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        metexB.acquire()
        print(f'{self.name} 抢到了B锁')
        metexB.release()
        metexA.release()

    def func2(self):
        metexB.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了B锁')
        time.sleep(2)
        metexA.acquire()
        print(f'{self.name} 抢到了A锁')
        metexA.release()
        metexB.release()


def main():
    for i in range(10):
        t = MyThread()
        t.start()


if __name__ == '__main__':
    main()
# Thread-1 抢到了A锁
# Thread-1 抢到了B锁
# Thread-1 抢到了B锁
# Thread-1 抢到了A锁
# Thread-2 抢到了A锁
# Thread-2 抢到了B锁
# Thread-2 抢到了B锁
# Thread-2 抢到了A锁
# Thread-4 抢到了A锁
# Thread-4 抢到了B锁
# Thread-4 抢到了B锁
# Thread-4 抢到了A锁
# Thread-6 抢到了A锁
# Thread-6 抢到了B锁
# Thread-6 抢到了B锁
# Thread-6 抢到了A锁
# Thread-8 抢到了A锁
# Thread-8 抢到了B锁
# Thread-8 抢到了B锁
# Thread-8 抢到了A锁
# Thread-10 抢到了A锁
# Thread-10 抢到了B锁
# Thread-10 抢到了B锁
# Thread-10 抢到了A锁
# Thread-5 抢到了A锁
# Thread-5 抢到了B锁
# Thread-5 抢到了B锁
# Thread-5 抢到了A锁
# Thread-9 抢到了A锁
# Thread-9 抢到了B锁
# Thread-9 抢到了B锁
# Thread-9 抢到了A锁
# Thread-7 抢到了A锁
# Thread-7 抢到了B锁
# Thread-7 抢到了B锁
# Thread-7 抢到了A锁
# Thread-3 抢到了A锁
# Thread-3 抢到了B锁
# Thread-3 抢到了B锁
# Thread-3 抢到了A锁

小结:

  • 死锁:两个或多个进程在执行时,因为抢占同一资源而产生了互相等待的现象
  • 递归锁:允许同一个线程多次请求同一个锁,称为递归的请求锁
posted @   苏苏!!  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示