python基础-死锁、递归锁
来源:互联网 发布:新闻网页源码 编辑:程序博客网 时间:2024/06/05 12:00
- 死锁
- 递归锁
死锁
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
from threading import Thread,Lockimport timemutexA=Lock()mutexB=Lock()class MyThread(Thread): def run(self): self.func1() self.func2() def func1(self): mutexA.acquire() print('\033[41m%s 拿到A锁\033[0m' %self.name) mutexB.acquire() print('\033[42m%s 拿到B锁\033[0m' %self.name) mutexB.release() mutexA.release() def func2(self): mutexB.acquire() print('\033[43m%s 拿到B锁\033[0m' %self.name) time.sleep(2) mutexA.acquire() print('\033[44m%s 拿到A锁\033[0m' %self.name) mutexA.release() mutexB.release()if __name__ == '__main__': for i in range(5): t=MyThread() t.start()
输出如下:
Thread-1 拿到A锁Thread-1 拿到B锁Thread-1 拿到B锁Thread-2 拿到A锁
分析如上代码是如何产生死锁的:
启动5个线程,执行run方法,假如thread1首先抢到了A锁,此时thread1没有释放A锁,紧接着执行代码mutexB.acquire(),抢到了B锁,在抢B锁时候,没有其他线程与thread1争抢,因为A锁没有释放,其他线程只能等待,然后A锁就执行完func1代码,然后继续执行func2代码,与之同时,在func2中,执行代码 mutexB.acquire(),抢到了B锁,然后进入睡眠状态,在thread1执行完func1函数,释放AB锁时候,其他剩余的线程也开始抢A锁,执行func1代码,如果thread2抢到了A锁,接下来thread2要抢B锁,ok,在这个时间段,thread1已经执行func2抢到了B锁,然后在sleep(2),持有B锁没有释放,为什么没有释放,因为没有其他的线程与之争抢,他只能睡着,然后thread1握着B锁,thread2要抢B锁,ok,这样就形成了死锁
递归锁
我们分析了死锁,那么python里面是如何解决这样的递归锁呢?
在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
from threading import Thread,Lock,RLockimport timemutexA=mutexB=RLock()class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): 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(5): t=MyThread() t.start()
输出代码如下:
E:\python\python_sdk\python.exe "E:/python/py_pro/3 死锁现象与递归锁.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-3 拿到A锁Thread-3 拿到B锁Thread-3 拿到B锁Thread-3 拿到A锁Thread-5 拿到A锁Thread-5 拿到B锁Thread-5 拿到B锁Thread-5 拿到A锁Process finished with exit code 0
或者如下的效果:
来解释下递归锁的代码:
由于锁A,B是同一个递归锁,thread1拿到A,B锁,counter记录了acquire的次数2次,然后在func1执行完毕,就释放递归锁,在thread1释放完递归锁,执行完func1代码,接下来会有2种可能,1、thread1在次抢到递归锁,执行func2代码 2、其他的线程抢到递归锁,去执行func1的任务代码
- python基础-死锁、递归锁
- python并发编程之多线程2------------死锁与递归锁,信号量等
- c 递归锁(重入锁) pthread_cond_wait 死锁
- 互斥锁、死锁、递归锁、信号量、Event
- Python基础-函数-递归函数
- Synchronized: 递归与死锁
- Python基础-递归和函数对象
- 守护进线程,互斥锁,信号量,队列,死锁递归锁等
- Python死锁和可重入死锁
- java基础(死锁)
- Java基础:死锁示例
- Python死锁问题查找
- Python死锁问题查找
- Python subprocess 死锁
- python中的死锁
- Python 多线程死锁
- 死锁(python 版)
- python基础(递归函数、匿名函数、文件)
- Retrofit网络请求参数注解,@Path、@Query、@QueryMap...
- UGUI制作人物展示功能
- 最通俗的SET、LIST和MAP
- 浏览器跳转
- Codeforces Round #449 (Div. 2) 总结(12.2)
- python基础-死锁、递归锁
- Android 浮雕遮罩滤镜(EmbossMaskFilter)
- 使用win10自带虚拟光驱打开ISO镜像文件
- Ardupilot下移植CAN总线驱动
- HDU1005Number Sequence
- 要提高SQL查询效率where语句条件的先后次序应如何写
- 大数据WEB阶段(十一)Ajax、URL编码
- Dollar Dayz
- Php-打印所有错误