【一】死锁
【1】介绍
-
死锁是指两个或多个进程,在执行过程中,因争夺资源而造成了互相等待的现象
-
即两个或多个进程持有各自的锁并视图获取对方持有的锁,从而导致阻塞,不能继续执行,一直僵在这
-
这种情况下,系统资源利用率极低,系统处于死循环状态
【2】例子
-
要吃饭,必须具备盘子和筷子
-
但是一个人拿着盘子等筷子。
-
另一个人拿着筷子等盘子
【3】解决方法
-
锁不要有多个,一个就足够
-
如果真的发生了死锁的问题,必须迫使一方先交出锁
【4】示例
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} 抢到了A锁") time.sleep(2) metexA.acquire() print(f"{self.name} 抢到了B锁") 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 抢到了A锁 # Thread-2 抢到了A锁 # 线程卡死 # 开启十个线程,第一个线程走完第一圈 回到原地抢A 结果第二个线程已经抢到A了 导致AB卡死
【二】递归锁
【1】介绍
-
递归锁(也叫可重入锁)是一种特殊的锁,它允许一个线程多次请求同一个锁,称为“递归地”请求锁
-
在该线程释放锁之前,会对锁计数器进行累加操作,线程每成功获得一次锁时,都要进行相应的解锁操作,直到锁计数器清零才能完全释放该锁。
-
递归锁能够保证同一线程在持有锁时能够再次获取该锁,而不被自己所持有的锁所阻塞,从而避免死锁的发生。
-
但是注意要正常使用递归锁,避免过多地获取锁导致性能下降。
【2】示例
-
可以被连续的 acquire 和 release
-
但是只能被第一个抢到这把锁上执行上述操作
-
他的内部有一个计数器,每acquire一次计数 +1 每release一次 计数-1
-
只要计数不为0,那么其他人都无法抢到该锁
from threading import Thread, 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} 抢到了A锁") time.sleep(2) metexA.acquire() print(f"{self.name} 抢到了B锁") 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 抢到了A锁 # Thread-1 抢到了B锁 # Thread-2 抢到了A锁 # Thread-2 抢到了B锁 # Thread-2 抢到了A锁 # Thread-2 抢到了B锁