一、什么是死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们将无法推进下去。
此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
系统发生死锁现象不仅浪费大量的系统资源,甚至导致整个系统崩溃,带来灾难性后果。
二、死锁产生的原因是什么?
死锁产生的四个必要条件
互斥使用:即当资源被一个线程使用(占有)时,别的线程不能使用
不可抢占:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放
请求和保持:即当资源请求者在请求其他资源的同时保持对原油资源的占有
循环等待:即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
产生原因
竞争资源引起进程死锁
当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。
三、如何避免(预防)和解决死锁?
1. 死锁预防——有序资源分配
这种算法资源按照某种规则将系统中的所有资源统一编号,申请时必须以上升的次序。系统要求申请流程:
a. 对它所必须使用的而且属于同一类的所有资源,必须一次申请完
b. 在申请不同类资源时,必须按照各类设备的编号依此申请。例如:进程PA,使用资源的顺序是R1,R2;进程PB,使用资源的顺序是R2,R1,若采用动态分配有可能形成环路条件,造成死锁。
采用有序资源分配法:R1的编号是1,R2的编号是2;
PA申请次序:R1,R2
PB申请次序:R1,R2
这样就破坏了环路条件,避免了死锁的发生
2. 死锁预防——银行家算法
把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中的状态有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的资源需求总量不能超过系统拥有的资源总数,银行算法进行资源分配可以避免死锁。
3. 死锁检测和解除
a. 死锁检测
定时监测
效率低时检测
进程等待时检测
b. 死锁解除
最简单、最常用的方法是进行系统的重新启动,不过这种方法代价很大,它意味着在这之前所有的进程已经完成的计算工作都将付之东流,包括参与死锁的那些进程,以及未参与死锁的进程;
撤销进程,剥夺资源。终止参与死锁的进程,收回它们占有的资源,从而解决死锁。这时又分为两种情况:一次性撤销参与死锁的全部进程,剥夺全部资源;或者逐步撤销参与死锁的进程,逐步收回死锁进程占有的资源。一般来说,选择逐步撤销的进程时要按照一定的原则进行,目的是撤销那些代价最小的进程,比如按进程的优先级确定进程的代价;考虑进程运行时的代价和与此进程相关的外部作业的代价等因素;
进程回退策略,即让参与死锁的进程会退至没有发生死锁前的某一点处,并由此点处继续执行,以求再次执行时不再发生死锁。虽然这个较为理想的办法,但是操作起来系统开销极大,要求堆栈这样的机构来记录进程的每一步变化,以便今后的回退,有时是无法做到的。
参考链接:
https://blog.csdn.net/changfengxia/article/details/80313822?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task