什么是死锁
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
产生原因
发生死锁时,进程永远不能完成,系统资源被阻碍使用,以致于阻止了其他作业开始执行。
必要条件,如果在一个系统中以下四个条件同时成立,那么就能引起死锁:
互斥:至少有一个资源必须处于非共享模式,即一次只有一个进程可使用。如果另一进程申请该资源,那么申请进程应等到该资源释放为止。
占有并等待:—个进程应占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有。
非抢占:资源不能被抢占,即资源只能被进程在完成任务后自愿释放。
循环等待:有一组等待进程 {P0,P1,…,Pn},P0 等待的资源为 P1 占有,P1 等待的资源为 P2 占有,……,Pn-1 等待的资源为 Pn 占有,Pn 等待的资源为 P0 占有。
我们强调所有四个条件必须同时成立才会出现死锁。循环等待条件意味着占有并等待条件,这样四个条件并不完全独立。
举个例子:
A进程需要读写文件F,就将指定内存值写入
B进程需要内存值为1,才会释放文件F的读写权
分析:
1. A进程有内存操作权却等待B释放文件
2. F文件被进程B独占
3. F文件不能被A强占
4. A等待B,B却等待A导致死锁
如何避免
资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
go中
go中协程调度也会造成死锁,于1.14中改进为基于信号的模式,抢占式调度。(另外sysmon也做了)
ps别的话题: 今天还不记得一个细节
当协程被关闭之后,之前写入的数据还是能从通道读取到,不会panic不会阻塞,直到数据读取完毕。