进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
1 from threading import Lock as Lock 2 import time 3 mutexA=Lock() 4 mutexA.acquire() 5 mutexA.acquire() 6 print(123) 7 mutexA.release() 8 mutexA.release() 9 10 死锁
解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
from threading import RLock as Lock import time mutexA=Lock() mutexA.acquire() mutexA.acquire() print(123) mutexA.release() mutexA.release() 递归锁RLock
典型问题: 科学家吃面
1 import time 2 from threading import Thread,Lock 3 noodle_lock = Lock() 4 fork_lock = Lock() 5 def eat1(name): 6 noodle_lock.acquire() 7 print('%s 抢到了面条'%name) 8 fork_lock.acquire() 9 print('%s 抢到了叉子'%name) 10 print('%s 吃面'%name) 11 fork_lock.release() 12 noodle_lock.release() 13 14 def eat2(name): 15 fork_lock.acquire() 16 print('%s 抢到了叉子' % name) 17 time.sleep(1) 18 noodle_lock.acquire() 19 print('%s 抢到了面条' % name) 20 print('%s 吃面' % name) 21 noodle_lock.release() 22 fork_lock.release() 23 24 for name in ['哪吒','egon','yuan']: 25 t1 = Thread(target=eat1,args=(name,)) 26 t2 = Thread(target=eat2,args=(name,)) 27 t1.start() 28 t2.start() 29 30 死锁问题
1 import time 2 from threading import Thread,RLock 3 fork_lock = noodle_lock = RLock() 4 def eat1(name): 5 noodle_lock.acquire() 6 print('%s 抢到了面条'%name) 7 fork_lock.acquire() 8 print('%s 抢到了叉子'%name) 9 print('%s 吃面'%name) 10 fork_lock.release() 11 noodle_lock.release() 12 13 def eat2(name): 14 fork_lock.acquire() 15 print('%s 抢到了叉子' % name) 16 time.sleep(1) 17 noodle_lock.acquire() 18 print('%s 抢到了面条' % name) 19 print('%s 吃面' % name) 20 noodle_lock.release() 21 fork_lock.release() 22 23 for name in ['哪吒','egon','yuan']: 24 t1 = Thread(target=eat1,args=(name,)) 25 t2 = Thread(target=eat2,args=(name,)) 26 t1.start() 27 t2.start() 28 29 递归锁解决死锁问题