立即学习:https://edu.csdn.net/course/play/24458/296445?utm_source=blogtoedu
1.死锁(Lock()的局限性)
知识点:Lock()只能被获得(acquire)一次,要想再次获得必须释放后才能获得
1)死锁情况1
#死锁情况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):#首先线程1获得了A锁,再获得B锁,最后两个都释放,开始进行f2中的B锁,因为沉睡了0.1秒,足以让线程2获得f1中的A锁,接下来线程1的工作是沉睡结束后获得A锁,线程2准备获得B锁,一直处于等待锁的释放,因为线程1和线程2都是在等待彼此手中的那把锁,因此形成了死锁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()
2)死锁情况2
#死锁情况2
from threading import Thread,Lock
import time
#设置了两把互斥锁,且是同一把锁
mutexA = mutexB = Lock()class mythread(Thread):def run(self):self.f1()def f1(self):#首先线程1获得了A锁,再获得B锁,最后两个都释放,开始进行f2中的B锁,因为沉睡了0.1秒,足以让线程2获得f1中的A锁,接下来线程1的工作是沉睡结束后获得A锁,线程2准备获得B锁,一直处于等待锁的释放,因为线程1和线程2都是在等待彼此手中的那把锁,因此形成了死锁mutexA.acquire()print('%s获取到了A锁'%self.name)mutexB.acquire()print('%s获取到了B锁'%self.name)mutexB.release()mutexA.release()if __name__ == '__main__':#线程切换的速度非常快,因此可以看成是依次线程执行的for i in range(10):t = mythread()t.start()
2.递归锁(RLock):可以解决死锁的问题
知识点:RLock(),
1)支持被同一个线程连续多次被获取(acquire),
2)内置一个计数器,同一线程每acquire一次,计数器+1,每release·一次,计数器-1,一直到计数器归零,这把递归锁才能被其他线程获取(acquire)
#递归锁情况
from threading import Thread,RLock
import time
#设置了两把互斥锁
mutexA = mutexB = RLock()class mythread(Thread):def run(self):self.f1()self.f2()def f1(self):#首先线程1获得了A锁计数器+1为1,再获得B锁计数器+1为2,最后两个都释放计数器归零,锁可以被其他线程获取,因为线程速度快,所以线程1获取到了f2的B锁,计数器为1,因为沉睡了0.1秒且线程1的计数器为1,虽然足以让线程2去获得f1中的A锁,但是条件不允许啊(计数器不归零),接下来线程1的工作是沉睡结束后获得A锁,计数器为2,线程1释放两次后计数器为0,线程2立马获得锁,不一定是线程2获得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()
#运行结果
'''
"F:\software install\python3.6.4\python.exe" C:/Users/jinlin/Desktop/python_further_study/并发编程/死锁与递归锁(Rlock).py
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锁进程已结束,退出代码0
'''