12 死锁

12.1死锁的基本概念

死锁的定义:一组进程中每个进程都无限等待被该组进程中另一进程所占有的资源,因而永远无法得到的资源,这种现象成为进程死锁,这一组进程就称为死锁进程:

  • 参与死锁的所有进程都在等待资源;
  • 参与死锁的进程是当前系统中所有进程的子集。

如果死锁发生,会浪费大量系统资源,甚至导致系统崩溃。

死锁出现的原因:整体系统中资源数量有限,锁和信号量错误使用。着重以资源数量来探讨,其中资源的使用方式:“申请——分配——使用——释放”模式。在当前的操作系统中,动态分配资源,如果有些进程得不到资源,将会处于等待阻塞状态,如果资源数量有限,则可能出现死锁。

资源分为:

  • 可重用资源——可被多个进程多次使用;
  1. 可抢占资源与不可抢占资源;
  2. 处理器(可抢占)、I/O部件、内存、文件、数据库、信号量。
  • 可消耗资源——只可使用一次,可创建和销毁的资源。例如信号、中断、消息。

死锁主要是针对可重用资源。

 

活锁(先加锁,再轮询——既无进展也没有阻塞)和饥饿(资源分配策略决定)需要与死锁加以区分。

 

产生死锁的必要条件(任何一个条件不成立,一定没有死锁发生):

  • 互斥使用(资源独占)——一个资源每次只能给一个进程使用;
  • 占有且等待(请求和保持,部分分配)——进程在申请新的资源的同时保持对原有资源的占有;
  • 不可抢占(不可剥夺)——资源申请者不能强行的从资源占有者手中夺取资源,资源只能由占有者自愿释放;
  • 循环等待——存在一个进程等待队列{P1,P2......Pn},其中P1等待P2占有的资源,P2等待P3占有的资源。。。。。Pn等待P1占有的资源,形成一个进程等待环路。

 

12.2资源分配图

资源分配图是为了解决死锁问题,用有向图描述系统资源和进程的状态,即可以用资源分配图来刻画某一时刻系统的状态,资源和进程的情况:

定义一个二元组G=(V,E):

V:结点的结合,分为P(进程),R(资源)两部分。P={P1,P2.....Pn};R={R1,R2......Rm};

E:有向边的集合,其元素为有序二元组。(Pi,Rj)或(Rj,Pi)。

 

资源分配图画法说明:

系统由若干类资源构成,一类资源称为一个资源类;每个资源类中包含若干个同种资源,称为资源实例。

资源类:用方框表示;

资源实例:用方框中的黑圆点表示;

进程:用圆圈中加进程名表示。

分配边:从资源实例——>进程;

申请边:从进程——>资源类。

 

针对资源分配图,给出死锁定理,即:

  • 如果资源分配图中没有环路,则系统中没有死锁,如果图中存在环路则系统中可能存在死锁;
  • 如果每个资源类中只包含一个资源实例,则环路是死锁存在的充分必要条件。

 

资源分配图化简步骤:

  1. 找一个非孤立、且只有分配边的进程结点,去掉分配边,将其变为孤立节点;
  2. 再把相应的资源分配给一个等待该资源的进程,即将该进程的申请边变为分配边。
  3. (3)重复(1)(2)

 

12.3死锁预防

解决死锁的方法有:

  • 鸵鸟算法(不考虑此问题);
  • 不让死锁发生;
  1. 死锁预防——静态策略:通过设计合适的资源分配算法,不让死锁发生;
  2. 死锁避免——动态策略:以不让死锁发生为目标,跟踪并评估资源分配过程,根据评估结果决策是否分配;
  • 让死锁发生:通过死锁检测判断是否真的发生死锁,然后采用一些方法解除死锁。

 

死锁预防:在设计系统时,通过确定资源分配算法,排除发生死锁的可能性。具体做法是:防止产生死锁的四个必要条件中任何一个条件发生。

  • 破坏“互斥使用/资源独占”条件;
  1. 资源转换技术:把独占资源变为共享资源;例如:SPOOLIING技术的引入,解决不允许任何进程直接占有打印机的问题。设计一个“守护进程/线程”负责管理打印机,进程需要打印时,将请求发给该daemon,由它完成打印任务。
  • 破坏“占有且等待”条件;
  1. 要求每个进程在运行前必须一次性申请它所要求的所有资源,且仅当该进程所要资源均可满足时才给予一次性分配。这种方案存在问题:资源利用率低,同时可能导致“饥饿”现象;
  2. 在允许进程动态申请资源前提下规定,一个进程在申请新的资源不能立即得到满足而变为等待状态之前,必须释放已占有的全部资源,若需要再重新申请。
  • 破坏“不可抢占”条件
  1. 实现方案:当一个进程申请的资源被其他进程占用时,可以通过操作系统抢占这一资源(两个进程优先级不同);局限性:适用于状态易于保存和恢复的资源,比如说CPU、内存。
  • 破坏“循环等待”条件——通过定义资源类型的线形顺序实现
  1. 实现方案:资源有序分配法。即把系统中所有资源编号,进程在申请资源时必须严格按资源编号的递增次序进行,否则操作系统不予分配。通常可以根据资源使用的频繁性编号。

 

12.4死锁避免

死锁避免定义:在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统发生死锁或可能发生死锁,则不予分配,否则予以分配。

安全状态:如果系统中存在一个由所有进程构成的安全序列P1,P2....Pn,则称系统处于安全状态。

安全序列:一个进程序列{P1,P2.....Pn}是安全的,即如果对于每一个进程Pi(1<=i<=n):它以后还需要的资源量不超过系统当前剩余资源量与所有进程Pj(j<i)当前占有资源量之和,则称系统处于安全状态。

不安全状态:系统中不存在一个安全序列。不安全状态一定会导致死锁。

 

12.5银行家算法——典型的死锁避免算法

dijlksta提出:仿照银行发放贷款时采取的控制方式而设计的一种死锁避免算法。

银行家算法的应用条件:

(1)在固定数量的进程中共享数量固定的资源;

(2)每个进程预先指定完成工作所需的最大资源数量;

(3)进程不能申请比系统中可用资源总数还多的资源;

(4)进程等待资源的时间是有限的;

(5)如果系统满足了进程对资源的最大需求,那么,进程应该在有限的时间内使用资源,然后归还给系统。

银行家算法的具体步骤:

当进程Pi提出资源申请时:

(1)若Request[i]<=Need[i],转(2);否则,报错返回;

(2)若Request[i]<=Available,转(3);否则,进程等待;

(3)假设系统分配了资源,则有:

Available=Available-Request[i];

Allocation[i]=Allocation[i]+Request[i];

Need[i]=Need[i]-Request[i];

若系统新状态是安全的,则分配完成,

若系统新状态是不安全的,则恢复原来状态,进程等待。

判断当前系统状态是否安全的方法:为进行安全性检查,定义数据结构:Work:ARRAY[1.....m]of integer;    Finish:ARRAY[1.......n]of boolean:

首先:进行数据结构的初始化。Work=Available;    Finish=False;

其次:寻找满足条件的i:

a. Finish[i]==false;即此进程还未被检查过;

b.Need[i]<=Work;即此进程还需要的资源数量可以被满足。

如果不存在,则转d

c.Work=Work+Allocation[i];    Finish[i]=true;转b;

d.若对所有i,Finish[i]==true,则系统处于安全状态,否则系统处于不安全状态。

 

12.6死锁检测与解除

死锁检测:允许死锁发生,但是操作系统会不断监视系统进展情况,判断死锁是否真的发生。一旦死锁发生则采取专门的措施,解除死锁并以最小的代价恢复操作系统运行。

检测时机:

  • 当进程由于资源请求不满足而等待时检测死锁(缺点是系统开销大);
  • 定时检测。即设定一个检测的周期;
  • 系统资源利用率下降时检测死锁(设定资源利用率阈值)。

 

一个简单的死锁检测算法:

  • 每个进程、每个资源指定唯一编号;
  • 设置一张资源分配表,记录各进程与其占用资源之间的关系;
  • 设置一张进程等待表,记录各进程与要申请资源之间的关系;
  • 通过分析资源分配表和进程等待表中是否出现进程等待环路来检测是否有死锁产生。

 

死锁的解除——重要的是以最小的代价恢复系统的运行:

  • 撤销所有死锁进程(代价比较大);
  • 进程回退(ROLL BACK)再启动,即在进程执行过程中,系统会为进程记录一些中间节点,当进程出现死锁之后,使这些产生死锁的进程退回到上一个中间节点,然后所有的进程再从上一个节点重新执行,因为死锁的产生是一个偶然现象,如果回退再启动,调度算法和并发环境变化之后,可能不会出现死锁问题(代价非常大,因为要记录很多节点);
  • 按照某种原则逐一撤销死锁进程,直到。。。。
  • 按照某种原则逐一抢占资源(资源被抢占的过程必须回退到之前的对应状态),直到。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值