进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
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 Lockimport timemutexA=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 递归锁解决死锁问题