【简记】Operating System——Dead Lock

来源:互联网 发布:车主名录软件 编辑:程序博客网 时间:2024/04/30 10:33

This memo is based on the course of Dr.Li with Operating System as the reference book.

本章内容:

  • 死锁的概念
  • 死锁发生的必要条件
  • 死锁预防
  • 死锁避免(安全性算法,银行家算法)
  • 死锁检测
  • 死锁恢复

7.1 死锁概念

如果在一个系统中下面4个条件同时满足, 那么会引起死锁。

① 互斥:至少有一个资源必须处于非共享模式,即一次只有一个进程使用。如果另一进程申请该资源,那么申请进程必须等到该资源被释放为止。
② 占有并等待: 一个进程必须占有至少一个资源,并等待另一资源,而该资源为其他进程所占有。
③ 非抢占:资源不能被抢占, 即资源只能在进程完成任务后自动释放。
④ 循环等待:有一组等待进程{P1, P2 …, Pn} P0等待的资源为P1 所占有, P1 等待的资源为P2 所占有, …… , Pn-1等待的资源为Pn 所占有, Pn 等待的资源为P0所占有。


7.3 死锁处理特征

包括UNIX和Windows认为死锁不可能在系统内发生,因此应用程序开发人员需要自己来处理死锁。


7.4 死锁预防

从死锁发生的四个必要条件出发来看如何预防。

7.4.1 互斥
通常不能通过否定互斥条件来预防死锁:有的资源本身就是非共享的。

===
7.4.2 占有并等待

必须保证: 当一个进程申请一个资源时,它不能占有其他资源。
策略1:每个进程在执行前申请并获得所有资源。(但是资源利用率低下)
策略2:允许进程在没有资源时才可申请资源。(可能发生饥饿。一个进程如需要多个常用资源,可能会永久等待,因为其所需要的资源中至少有一个己分配给其他进程)

===
7.4.3 非抢占

如果一个进程占有资源并申请另一个不能立即分配的资源,那么其现已分配的资源都可被抢占。

一个进程要重新执行,它必须分配到其所申请的资源, 并恢复其在等待时被抢占的资源。

这个协议通常应用于状态可以保存和恢复的资源,如CPU 寄存器和内存。它一般不适用于其他资源,如打印机和磁带驱动器。

===
7.4.4 循环等待

一个确保此条件不成立的方法是对所有资源类型进行完全排序,且要求每个进程按递增顺序来申请资源。

这里写图片描述

但是代价极高,且函数很难设计。

总结:有些必要条件无法被避免,如互斥;其他条件要预防也要付出极大代价,得不偿失。在通用操作系统上很难实现。


7.5 死锁避免

根据每个进程可能申请的每种资源类型实例的最大需求的事先信息,可以构造一个算法以确保系统决不会进入死锁状态。死锁避免算法动态地检测资源分配状态以确保循环等待条件不可能成立。

资源分配状态是由可用资源,己分配资源,及进程最大需求所决定的。下面来研究两个死锁避免算法。

7.5.1 安全状态

进程顺序< P1,P2,… , Pn > 如果对于每个Pi, Pi仍然可以申请的资源数小于当前可用资源加上所有进程Pj(其中j < i) 所占有的资源,那么这一顺序称为安全序列。

在这种情况下,进程Pi所需要的资源即使不能立即可用,那么Pi 可等待直到所有Pj释放其资源。当它们完成时,Pi可得到其所需要的所有资源,完成其给定任务,返回其所分配的资源井终止。

当Pi终止时, Pi+1可得到其所需要的资源,如此进行。

这里写图片描述

不安全状态可能会发生死锁,安全状态一定不会发生死锁。

===
7.5.3 dijkstra算法银行家算法

  • 当新进程进入系统时,它必须说明其可能需要的每种类型资源实例的最大数量,这一数量不能超过系统资源的总和。
  • 当用户申请一组资源时,系统必须确定这些资源的分配是否仍会使系统处于安全状态。如果是,就可分配资源;否则,进程必须等待直到某个其他进程释放足够资源为止。
  • 申请资源后,可能被要求等待
  • 必须在有限时间内归还

为了实现银行家算法,必须有几个数据结构。这些数据结构对资源分配系统的状态进行了记录。设n 为系统进程的个数, m 为资源类型的种类。需要如下数据结构:
这里写图片描述

1.安全性算法
(首先work数组是各个资源目前可用的数量,Finish数组记录线程顺序执行情况,从第一个线程开始
步骤解析:第二步是确认当前线程的need小于可用的资源数;第三步将work更新,即加上先前线程结束后释放的资源,然后重复第二步,直到所有线程都满足;如果中途有线程不满足,则跳出循环,认为系统状态是不安全的)
这里写图片描述
2.资源请求算法
这里写图片描述
上述第③步会调用安全性算法,判断是安全序列,则可以贷款。


7.6 死锁检测

定义变量(类似之前的死锁避免里的安全性算法,但少了一个矩阵,因为该算法是要做检测,所以request是实时的值,不需要预测)
这里写图片描述

这里写图片描述

什么时候触发死锁检测:

  • request请求大
  • CPU利用率低
  • 定时检测

7.7 死锁恢复

7.7.1 进程终止

  • 终止所有死锁进程
  • 一次只终止一个进程直到取消死锁循环为止

选择杀死哪个进程:
① 进程的优先级是什么?
② 进程己计算了多久,进程在完成指定任务之前还需要多久?
③ 进程使用了多少什么类型的资源( 例如,这些资源是否容易抢占)
④ 进程需要多少资源以完成?
⑤ 多少进程需要被终止?
⑥ 进程是交互的还是批处理的?

7.7.2 资源抢占

通过抢占资源以取消死锁, 逐步从进程中抢占资源给其他进程使用, 直到死锁环被打破为止。

如果要求使用抢占来处理死锁,那么有三个问题需要处理:
① 选择一个牺牲品:抢占哪些资源和哪个进程?与进程取消一样,必须确定抢占顺序以使代价最小化。代价因素包括许多参数,如死锁进程所拥有的资源数量,死锁进程到现在为止在其执行过程中所消耗的时间。

② 回滚:如果从一个进程那里抢占一个资源,那么应对该进程做些什么安排?显然,该进程不能正常执行,它缺少所需要的资源。必须将进程回滚到某个安全状态,以便从该状态重启进程。通常确定一个安全状态并不容易,所以最简单的方法是完全回滚:终止进程并重新执行。更为有效的方法是将进程回滚到足够打破死锁。另一方面,这种方法要求系统维护有关运行进程状态的更多信息。

③ 饥饿:如何确保不会发生饥饿?即如何保证资源不会总是从同一个进程中被抢占?如果一个系统是基于代价来选择牺牲进程,那么同一进程可能总是被选为牺牲品。结果,这个进程永远不能完成其指定任务,任何实际系统都需要处理这种饥饿情况。显然,必须确保一个进程只能有限地被选择为牺牲品。最为常用的方法是在代价因素中加上回滚次数。