并发编程中关于死锁,递归锁,信号量的理解
并发编程中关于死锁,递归锁,信号量的理解
1.死锁****
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
产生死锁的情况:1.对一把互斥锁加锁多次
2.一个共享资源 要访问必须同时具备多把锁,但是这些锁被不同线程或进程所持有 , 就会导致相互等待对方释放 从而程序就卡死了
from threading import Thread,Lock
import time
mutexA=Lock()
mutexB=Lock()
class MyThread(Thread):
def run(self):
self.func1()
self.func2()
def func1(self):
mutexA.acquire()
print('\033[41m%s 拿到A锁\033[0m' %self.name)
mutexB.acquire()
print('\033[42m%s 拿到B锁\033[0m' %self.name)
mutexB.release()
mutexA.release()
def func2(self):
mutexB.acquire()
print('\033[43m%s 拿到B锁\033[0m' %self.name)
time.sleep(2)
mutexA.acquire()
print('\033[44m%s 拿到A锁\033[0m' %self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
#同时开启10个线程
for i in range(10):
t=MyThread()
t.start()
#Thread-1 拿到A锁
#Thread-1 拿到B锁
#Thread-1 拿到B锁(线程1执行完b上锁以后,睡眠2s后,但此时线程2率先抢到a锁,所以等进程2的a锁解开后,才能运行进程1中的fun2的a锁运行,但此时进程2中需要b锁,但进程1中的b锁并未解开,所以产生死锁)
#Thread-2 拿到A锁
2.递归锁
特点:1.多线程之间都有互斥的效果,不同在于,同一个线程可以对同一个锁进行多次acquire
2.同一个线程必须保证加锁和解锁次数相同,其他线程才能够抢到这把锁
3.信号量
可以限制同时并发执行公共代码的线程数量,如果限制数量为1,则与普通互斥锁没有区别
from threading import Semaphore,current_thread,Thread
import time
s = Semaphore(2)#同一时间最大并发2个
def task():
s.acquire()
time.sleep(1)
print(current_thread().name)
s.release()
for i in range(10):
Thread(target=task).start()
# 注意:信号量不是用来解决安全问题的 而是用于限制最大的并发量