在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去。

下面是一个死锁的例子:

#-*-conding:utf-8-*-
import threading
import time

A = threading.Lock()
B = threading.Lock()

class TestThread(threading.Thread):

def runA(self):
A.acquire()             #2步骤 5个线程其中一个线程肯定会获取A这把锁,另外4个线程必须在这个位置等着A这把锁释放. #15步骤,此时此刻线程获取了A锁
print(self.name,'get A',time.ctime()) #3步骤 打印了一条信息 #16步骤,打印了一条信息
time.sleep(2)              #4步骤 睡2秒                                      #17步骤,睡2秒
  
B.acquire()               #5步骤 Thread-1线程A锁,在没释放的情况下,有获得了一把B锁(也就是说A锁里面套着B锁)     #18步骤,开始获取B锁;这就出问题了,因为B锁这时候是线程1拿着,线程1等着线程2释放A锁才能继续,线程2有等着线程1释放B锁才能继续,走到就相互等着对方释放卡死了(这就叫死锁)
print(self.name, 'get B', time.ctime()) #6步骤 打印了一条信息
time.sleep(1)             #7步骤 睡一秒,(上面4个线程还一直在等待)

B.release()               #8步骤 释放B锁后,上面的4个线程还在等待,因为A锁没释放
A.release()               #9步骤 释放A这把锁,这时候第Thread-2二个线程开始运行,有开始获取A这把锁


def runB(self):               #10步骤 此时,Thread-1;线程1继续运行执行runB方.
B.acquire()               #11步骤,Thread-1 线程1 接着获取到B这把锁,机会同一时候第二个线程获取了A锁,第一个线程获取了B锁
print(self.name, 'get B', time.ctime()) #12步骤,打印了一个消息
time.sleep(2) #13步骤,睡2秒

A.acquire()               #14步骤,线程1有获取A锁,此时A锁已经被线程2获取了;所有线程1走到的时候,需要等待线程2释放A锁后,才能继续往下走
print(self.name, 'get A', time.ctime())
time.sleep(1)

A.release()
B.release()

def run(self):
self.runA()
self.runB()


if __name__ == '__main__':
l = []
for i in range(5):  #1步骤 开启5个线程
t = TestThread()
t.start() #执行run方法
l.append(t)

for i in l:
i.join()

print('end threading')

递归锁
#-*-conding:utf-8-*-
import threading
import time
A = threading.RLock()         #递归锁 (锁里面维护着一个计数器,当获取一把锁计数器加1 当释放一把锁计数器减一,当递归锁计数器为零线程之间就开始竞争)
class TestThread(threading.Thread):
def runA(self):
A.acquire()           #线程1获取A锁 计数器加1
print(self.name,'get A',time.ctime())
time.sleep(2)

A.acquire() #线程1再次获取A 也就是说线程1获取第一次那把锁,线程1再拿过来锁下面的内容(都是一把锁) 计数器在加1 现在是2
print(self.name, 'get B', time.ctime())
time.sleep(1)

A.release()           #释放
A.release()           #释放 到这现在递归锁全部释放

def runB(self):
A.acquire()           #这时候线程1 有想获取递归(线程能否获得,不一定获得,因为还有4个线程等着获取锁),此时还有4个线程也在等待获取锁,这时候这4个线程和当前线程1会开始竞争,如果线程1竞争胜利,就继续运行(其他线程都无法执行任何代码),如果竞争失败,其他的胜利的线程运行(线程1就在此处等着,下一次胜利,就在这开始运行代码),以此类推
print(self.name, 'get B', time.ctime())
time.sleep(2)

A.acquire()
print(self.name, 'get A', time.ctime())
time.sleep(1)

A.release()
A.release()

def run(self):
self.runA()
self.runB()

if __name__ == '__main__':
l = []
for i in range(5):
t = TestThread()
t.start()
l.append(t)

for i in l:
i.join()

print('end threading')


 
posted on 2018-06-01 14:06  Python哥  阅读(206)  评论(0编辑  收藏  举报