在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
import threading
import time
class MyThread1(threading.Thread):
def run(self):
# 对mutexA上锁
mutexA.acquire()
# mutexA上锁后,延时1秒,等待另外那个线程 把mutexB上锁
print(self.name+'----do1---up----')
time.sleep(1)
# 此时会堵塞,因为这个mutexB已经被另外的线程抢先上锁了
mutexB.acquire()
print(self.name+'----do1---down----')
mutexB.release()
# 对mutexA解锁
mutexA.release()
class MyThread2(threading.Thread):
def run(self):
# 对mutexB上锁
mutexB.acquire()
# mutexB上锁后,延时1秒,等待另外那个线程 把mutexA上锁
print(self.name+'----do2---up----')
time.sleep(1)
# 此时会堵塞,因为这个mutexA已经被另外的线程抢先上锁了
mutexA.acquire()
print(self.name+'----do2---down----')
mutexA.release()
# 对mutexB解锁
mutexB.release()
mutexA = threading.Lock()
mutexB = threading.Lock()
if __name__ == '__main__':
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
这个阻塞在于:两个重复上锁:
一个线程给A上锁,另一个再给A上锁时就阻塞了
或者另外一种方式,在一个线程里加多把锁,也会出现类似的现象
比如在线程中:
def add1(nums,mutex):
global num
mutex.acquire()
mutex.acquire()
for i in range(nums):
num+=1
mutex.release()
mutex.release()
#这样就会阻塞,不会向下进行
#time.sleep(1)
print(f'-----add1----{num}')
加了2把锁就出现了类似的现象
- 重入锁:
- mutex = threading.RLock() 这种锁叫重入锁,将锁换成这种锁后就可以解决多把锁的阻塞问题
- 重入锁在加多把锁时不会造成死锁
- 不过无论是什么锁,加锁的数量和解锁的数量必须是一样的
- 代码实现:
def main():
# mutex = threading.Lock()
mutex = threading.RLock()#重入锁 可以解决多把锁阻塞的问题
t1 = threading.Thread(target=add1,args=(1000000,mutex))
t2 = threading.Thread(target=add2,args=(1000000,mutex))
t1.start()
#time.sleep(1)
t2.start()
t1.join()
t2.join()
print(f'-----main-----{num}')
在这里只把锁改了,之前阻塞的程序变得不再阻塞