1、死锁产生的原因:
是由进程请求和占有资源引起的
2、死锁产生的必要条件:
(1)互斥条件:
指的是某一个临界资源只能被一个进程占有,如果其他进程想要使用该资源必须等待该临界资源被释放才能使用
(2)请求和保持条件:
指的是进程在请求其他资源的时候并不释放自身所拥有的资源
(3)不可剥夺条件:
指的是该进程自身所拥有的资源只能是程序用完之后进行释放,其他进程不可以剥夺该进程的资源,即使该进程此时可能并不运行
(4)环路条件:
一组进程{P1,P2……Pn}的资源占有情况与请求资源的情况构成了一个环形链
3、如何解决死锁:
(1)预防死锁:
死锁的预防主要是从产生死锁的四个必要条件开始入手,打破其中的一个必要条件就可以破坏死锁
①一次性分配方案:(针对请求与保持提出的解决措施)
将需要使用到的资源一次性全部分配,当进程开始运行的时候就不可以再申请资源了。
缺点:
资源的浪费:该进程一开始就拥有所需的全部资源,那么有些资源在进程运行的最后才需要使用,但是在进程刚开始运行的时候就进行了分配,从而使得这类资源一大部分时间都被闲置,造成资源浪费。
资源需求多的进程会“饥饿”:如果某些进程需要的资源比较多,但是它所需的资源由于没有被释放一直无法申请,造成进程一直无法正常执行。
资源清单不准确:如果一开始确定需要的所有资源清单出现不准确的问题,在进程的执行过程中如果还需要其他资源但是由于无法再次申请,导致进程无法继续执行。
②资源可剥夺方案:(针对不可剥夺提出的解决措施)
进程在运行的过程中需要什么资源再去进行资源的申请,但是如果某一资源无法申请,那么就将该进程阻塞并将自身拥有的资源全部释放供其他进程使用,等待资源充足的时候在重新分配资源并恢复运行。
缺点:
实现起来比较复杂:当有进程因为无法申请到所需资源而释放自己的所有资源时,系统的可用资源不仅要增加,还要将释放的这些资源的使用进度记下来,以便事后该进程接着上下文运行。
剥夺进程的资源需付出代价:比如一个进程的打印机被系统剥夺,那么之前打印的数据就被丢失,当该进程重新获得打印机的时候就需要重新打印。
程序推迟运行:由于进程会在运行中释放资源、申请资源,所以推迟了进程的周转时间。
③资源有序使用方案:(针对环路条件提出的解决措施)
进程申请的资源编号必须是严格按照升序或者降序进行,不能一部分按照资源的降序编号进行申请,一部分按照资源的升序编号进行申请。
缺点:
资源的编号相对稳定:如果资源的编号经常进行改变,用户不可接收,此外编号的稳定限制了新资源的添加,对系统的功能扩充不利。
资源浪费:如果要求按照升序申请资源,那么编号较低的资源最先被申请到但是在进程的运行过程中最后使用,这就会造成资源的浪费。
用户使用不便:要求用户必须按照一定的顺序申请资源,这在一定程度上限制了用户思想发挥。
(2)死锁避免:
①安全状态:
当系统存在一个进程序列,是系统按照次序列机型推进,所有进程都可以顺利执行完毕,那么这样的序列成为安全序列。所以判断系统当前是否处于安全状态就看是否有一个安全序列。
例如:进程需要某一个资源,系统可以先将资源试探性地分配给该进程,然后判断系统是否处于安全状态,如果处于不安全状态,就将此资源推迟分配。
②银行家算法:
银行家算法需要建立多种数据结构,具体如下:
~可用资源向量available:记录每一种资源可用量为多少个
例如:可用资源向量为:3 3 2,表示第一类资源可用量有3个,第二类资源的可用量为3个,第三类资源的可用量为2个
~需求总量矩阵max:记录进程对每一种资源的需求。
例如:需求总量矩阵为:7 5 3,表示第一类资源总共需求7个,第二类资源……以此类推
~资源占有矩阵allocation:记录当前进程占有每一类资源的情况
~资源缺口矩阵need:记录当前进程还需要的每一类资源的具体情况
算法思路如下:
假如进程资源请求向量为request,
第一步:判断request>need:说明进程现在的请求资源数超过了它之前所说的需求最大值,系统就会拒绝分配
第二步:request>available:说明系统当前的资源不足以满足进程的需求,所以会将该进程阻塞并推迟分配
第三步:试探性的将资源进行分配:
available-=request;
allocation+=request;
need-=request;
第四步:调用安全算法safe(),测试系统是否安全
(3)检测死锁:
系统在运行的过程中有三种进程:孤立进程、非阻塞进程以及阻塞进程。
所谓的检测死锁就是:当非阻塞进程执行完毕,释放占有的资源后,让有些阻塞的进程从死锁中解除并继续执行,执行结束释放更多的资源以供其他阻塞的进程所需,从而排除更多的阻塞进程,直到最后排除所有可满足的进程为止,然后再去检测是否还有阻塞的进程,如果还有说明此时系统出现了死锁,否则则不再有死锁。
(4)消除死锁:
①撤销进程法:
撤销部分死锁进程,用释放的资源来救活其他死锁的进程
②资源剥夺法:
当系统检测到死锁的时候,将该进程由“阻塞”状态转为“挂起状态”,并剥夺该进程的所有资源,保存它在挂起点前的状态,当该进程被激活后,恢复挂起点前的状态并重新为它分配资源。