上一篇我们初步讲解了关于多线程的创建,启动,以及锁的运用
今天我们继续看关于锁的更多内容,递归锁,递归锁和Rlock,使用和lock差不多但是有一点,当rlock的调用数量大于0,其它线程将无法得到锁,
我们先看一下为什么引进递归锁
import threading
import time
#死锁
class Threads(threading.Thread):
def actionA(self):
A.acquire()
print(self.name,"gotA",time.ctime())
time.sleep(1)
B.acquire()
print(self.name,"gotB",time.ctime(1))
time.sleep(2)
B.release()
A.release()
def actionB(self):
B.acquire()
print(self.name,"gotB",time.ctime())
time.sleep(1)
A.acquire()
print(self.name,"gotA",time.ctime(1))
time.sleep(2)
A.release()
B.release()
def run(self):
self.actionA()
self.actionB()
if __name__ == '__main__':
L=[]
A=threading.Lock()
B=threading.Lock()
for i in range(5):
t = Threads()
t.start()
L.append(t)
for i in L:
i.join()
print('ending****')
运行上面的代码,结果如下,我们发现程序会被卡住(当然也有肯不会被卡住,这需要看线程抢占锁是否冲突,如果一直是一个线程抢占到所有的锁,继续瞒住运行条件,那么就不会被卡住,但是这种情况是很少见的)
我们可以看到程序被卡住的位置,那么我们分析一下为什么程序会被卡住
我们创建了五个线程,当线程一执行到actionA时会首先将获取A,B锁,此时其他线程无法获取锁,因此会等待线程一释放锁
其他线程才能够继续运行,那么等待线程一释放锁,其他线程会立即执行抢占锁,就出现了上图所示的结果,线程一继续运行,在actionB中获取了B锁,而线程二在action中获取了A锁导致两个线程无法瞒住继续运行的条件而被卡住,
我们解决的办法就是采用Rlock,我们先看代码
import threading
import time
class Threads(threading.Thread):
def actionA(self):
r_lock.acquire() #采用rlock
print(self.name,"gotA",time.ctime())
time.sleep(1)
r_lock.acquire()
print(self.name,"gotB",time.ctime(1))
time.sleep(1)
r_lock.release()
r_lock.release()
def actionB(self):
r_lock.acquire()
print(self.name,"gotB",time.ctime())
time.sleep(1)
r_lock.acquire()
print(self.name,"gotA",time.ctime(1))
time.sleep(2)
r_lock.release()
r_lock.release()
def run(self):
self.actionA()
self.actionB()
if __name__ == '__main__':
L=[]
# A=threading.Lock()
# B=threading.Lock()
r_lock = threading.RLock() #注意 采用的锁不同
for i in range(5):
t = Threads()
t.start()
L.append(t)
for i in L:
i.join()
print('ending****')
我么看一下执行结果
如上是运行的结果我们先看一下结果这次每个线程交替运行了
#采用Rlock,rlock作为一个标志,当rlock大于0则其他线程无法拿到锁,而已经获取的线程是可以继续获取
这就可以能得出为什么上述两种情况的不同了
lock可以任意线程获取但是只能有一个线程获取
rlock只有获取的线程才能够继续获取