一. 死锁定义
死锁(Deadlock)是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
举例:毕业生找工作,公司表示只需要有工作经验才可以来;要想有工作经验,就需要去公司工作......
二.产生死锁的条件
1.互斥性:线程对资源的占有是排他性的,一个资源只能被一个线程占有,直到释放。
2.请求和保持条件:一个线程对请求被占有资源发生阻塞时,对已经获得的资源不释放。
3.不可抢占:一个线程在释放资源之前,其他的线程无法剥夺占用。
4.循环等待:发生死锁时,线程进入死循环,永久阻塞。
三.预防死锁
在编写程序的时候,针对死锁条件进行预防:
1) 破坏“请求和保持”条件
a. 进程在执行前必须一次性申请完所有执行期间所需资源
b. 进程提出申请资源前需要释放所有资源
2) 破坏“不可抢占”条件
a.申请资源时,如果有,则申请成功;如果无,则释放所有资源
b.申请资源时,如果有,则申请成功;如果无,则抢占拥有该资源且处于等待状态的线程的该资源
3) 破坏“循环等待”条件
将资源编号,每个线程只能按递增顺序申请资源,若需要低序号的资源,则需要释放当前所拥有的资源
四.避免死锁
若程序已经编写完毕,无法进行预防了,采用银行家算法避免死锁
银行家算法:保证每次分配资源后程序都处于安全状态
简单理解:
安全状态:当前至少有一个进程可以用剩余的资源完成运行
当一个进程申请某一项资源,若无该资源,拒绝该申请;若有,假设将该资源分配给了该程序,然后判断当前是否处于安全状态,若不处于,则拒绝该申请,若处于安全状态,则通过该申请
五.死锁检测
构建资源分配图:将进程和资源画在一张图上;进程每需要一项资源,则从进程引出一条有向边指向相应的资源,进程每成功申请到一项资源,则从资源引一条有向边指向进程
举例(来源于知乎):进程P1,P2, 资源R1有3个, R2有2个,P1已经申请了2个R1,请求1个R2,P2已经申请了1个R1和1个R2,需要1个R1
死锁定理:
1)在资源分配图中,找出既不阻塞又不孤点的进程P(既找出一条有向边与它相连,且该有向边对应的资源的申请量小于等于系统中已有的空闲资源数量),消去它所有的请求边和分配边,使之成为孤立的节点。
2)进程P所释放的资源,可以唤醒某些因等待这些资源而阻塞的进程,原来的阻塞进程可能变为非阻塞进程。
举例(来源于知乎):
若简化后的资源分配图依旧存在环,则存在死锁
六.解除死锁
1)资源剥夺法。将一些死锁进程暂时挂起来,并且抢占它的资源,并将这些资源分配给其他的死锁进程 ,要注意的是应该防止被挂起的进程长时间得不到资源而处于资源匮乏的状态
2)撤销进程法。强制撤销部分甚至全部死锁并剥夺这些进程的资源。撤销的原则可以按照进程优先级和撤销进程的代价高低进行。
3)进程回退法,让一或多个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而非被剥夺。这个方法要求系统保持进程的历史信息,并设置还原点。
资料: