操作系统学习笔记(七)-- 死锁

Posted on 2016-04-02 11:16  paulingzhou  阅读(897)  评论(0编辑  收藏  举报

最近开始学习操作系统原理这门课程,特将学习笔记整理成技术博客的形式发表,希望能给大家的操作系统学习带来帮助。同时盼望大家能对文章评论,大家一起多多交流,共同进步!

本文主要分以下几个方面:

  • 系统模型(System Model)
  • 死锁特征(Deadlock Characterization)
  • 死锁的处理方式
    • 死锁的预防(Deadlock Prevention) -- 设计无锁系统
    • 死锁的避免(Deadlock Avoidance)
    • 死锁的监测(Deadlock Detection)
    • 从死锁状态恢复(Recovery from Deadlock)

死锁的定义:两个或两个以上进程由于竞争资源而导致系统无法推进,则称系统所处的状态为死锁。死锁为一种僵局。

举例:

  系统有两个磁带设备(慢速设备,临界资源)

  P1,P2各持有一个磁带设备并需要另一个

  信号量A或B,初始化为1。

P0:                              P1:
wait(A);                       wait(B);
wait(B);                       wait(A);

 下图为死锁的示意图:

死锁产生原因:

  1. 资源相对不足;
  2. 进程推进的次序不合理

 必要条件:

  1. 互斥条件 Mutex exclustion:对资源的使用只能互斥不能共享
  2. 占有并等待 Hold and wait
  3. 非抢占/非剥夺 No preemption
  4. 循环等待/环路等待 Circular wait:系统对资源的申请和使用构成环路

故死锁为系统的一种可能性。

 

系统模型(System Model)

系统资源:R1,R2,...,Rm

      CPU cycles, memory space, I/O device

每一个资源类型Ri都有Wi个实例。

每一个进程使用资源必须遵从:请求->使用->释放 的次序。

资源分配图(Resource-Allocation Graph)

一个由节点V和边E组成的集合

V可以分为两部分:

  • P={P1,P2,...,Pn},系统进程构成的集合;
  • R={R1,R2,...,Rn},系统资源构成的集合。

请求边:有向边 Pi -> Rj

分配遍:有向边 Rj -> Pi

资源分配图举例:该资源分配图未构成死锁,因没有环路

死锁的基本事实:

  • 一个图不构成环路  ->  不构成死锁
  • 图包含一个回路  ->
    • 如果每个资源只有一个实例,则构成死锁
    • 如果每个资源有不止一个实例,则有可能构成死锁

对待死锁的处理态度:

  1. 确保系统永远不会进入死锁状态
  2. 允许系统进入死锁状态,并处理死锁
  3. 忽略死锁问题并假定系统永不发生死锁

死锁的预防(Deadlock Prevention)

破坏死锁的四个必要条件之一,构建一个无死锁系统:互斥和非抢占无法破坏,可破坏占有并等待,即使用一次性资源分配法,缺点为资源浪费严重;可破坏环路等待,即使用有序资源使用法,经所有资源编号,只能按资源编号顺序申请

死锁的避免(DeadLock Avoidance)

执行一个死锁的避免算法来确保不会发生环路等待:银行家算法

每个进程声明美中类型资源的最大需求量,动态监测。

当一个进程请求一个可用资源时,系统必须确定分配该资源后系统是否处于安全状态。

安全状态:当所有进程都能存在安全序列时系统处于安全状态。

安全序列:即系统可以通过该序列合法调度所有进程。

银行家算法:

  • 多实例
  • 每一个进程预先声明最大的资源需求量
  • 一个进程申请资源时可能等待
  • 完成后释放资源

银行家算法的数据结构:

Available:m阶的数组,Available[j]=k表示j类资源还有k个;

Max: n*m的矩阵,Max[i,j]=k表示Pi类进程申请Rj类资源最多k个;

Allocation:n*m的矩阵,Allocation[i,j]=k表示Pi类进程已经占用Rj类资源k个;

Need:n*m的矩阵,Need[i,j]=k表示Pi类进程还需Rj资源k个  Need[i,j]=Max[i,j]-Allocation[i,j]

安全性算法:

  1. 假设Work和Finish为两个m维和n维的工作向量,初始化:Work:=Availble  Finish:=false for i = 1,2,...,n
  2. 找满足以下条件:(a)Finish[i]=false; (b)Needi <= work; If no such i exists, go to step 4
  3. Work:= Work + Allocation; Finish[i]:=true; go to step 2
  4. If Finish[i]=true for all i, then the system is in a safe state

算法的主题过程

Requesti = request vector for process Pi. If requesti[j]=k then process Pi wants k instance of resource type Rj.

1. 合理性检查 If requesti <= Needi go to step 2; otherwise, raise error condition.

2. 预分配 If requesti <= Available, go to step 3; otherwise Pi must wait

3. 安全性检测

If safe => the resources are allocated to Pi

If unsafe => Pi must wait, and the old resource-allocation state is stored

死锁检测(Deadlock Detection)

  • 允许系统进入死锁状态
  • 检测算法
  • 恢复机制

Maintain wait-for graph

  • 节点为进程
  • Pi->Pj表明Pi在等待Pj

系统周期性的调用算法判断图中是否有环路。

其过程(Available, Allocation, Request)类似于银行家算法。

调用该检测算法的频度和时间:

  1. 死锁发生的频率
  2. 有多少进程需要回滚

若检测方法被随意调度,则可能会出现多个环路,即多个进程进入危险区。

死锁的恢复(Detection Algorithm)

终止进程:可能会导致时间浪费或进程同步间的问题

  终止在死锁状态的所有进程

  每次终止一个进程知道死锁环路消除

选择终止的进程次序:

  1. 进程已运行时间和预计还需运行时间
  2. 优先级
  3. 进程已经使用的资源
  4. 进程完成还需使用的资源
  5. 解除死锁需要终止进程的数量
  6. 进程为交互性的还是批处理的

剥夺资源(Resource Preemption)

以最小成本寻找进程的牺牲者。

回滚:回退到某个安全时刻,在该进程重启进程

饥饿:有一些进程可能永远被选作牺牲者