操作系统学习笔记010

死锁

在计算机系统中有很多独占性的资源,在任一时刻它们都只能被一个进程使用。(如打印机、磁带、系统内部表中的表项)在很多应用中,需要一个进程排他性地访问若干种资源而不是一种。死锁也可能发生在机器之间。软硬件资源都有可能出现死锁。
本章重点:考察几类死锁,了解它们是如何出现的,学习防止或者避免死锁的办法。

1 资源

类需要排他性使用的对象称为资源(resource)。资源可以是硬件设备(如磁带机)或是一组信息(如数据库中一个加锁的记录)。

1.1 可抢占资源和不可抢占资源

可抢占资源(preemptable resource)可以从拥有它的进程中抢占而不会产生任何副作用,存储器就是一类可抢占的资源。不可抢占资源(nonpreemptable resource)是指在不引起相关的计算失败的情况下,无法把它从占有它的进程处抢占过来。死锁和不可抢占资源有关,有关可抢占资源的潜在死锁通常可以通过在进程之间重新分配资源而化解。
使用一个资源所需要的事件顺序可以用抽象的形式表示如下:
1)请求资源。
2)使用资源。
3)释放资源。

1.2 资源获取

有时候,进程需要两个或更多的资源,它们可以顺序获得。如果需要两个以上的资源,通常都是连续获取。

2 死锁概述

如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么,该进程集合就是死锁的。

2.1 资源死锁的条件

1)互斥条件。每个资源要么已经分配给了一个进程,要么就是可用的。
2)占有和等待条件。已经得到了某个资源的进程可以再请求新的资源。
3)不可抢占条件。已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
4)环路等待条件。死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待着下一个进程所占有的资源。

有四种处理死锁的策略:
1)忽略该问题。也许如果你忽略它,它也会忽略你。
2)检测死锁并恢复。让死锁发生,检测它们是否发生,一旦发生死锁,采取行动解决问题。
3)仔细对资源进行分配,动态地避免死锁。
4)通过破坏引起死锁的四个必要条件之一,防止死锁的产生。

3 鸵鸟算法

如果死锁平均每5年发生一次,而每个月系统都会因硬件故障、编译器错误或者操作系统故障而崩溃一次,那么大多数的工程师不会以性能损失和可用性的代价去防止死锁。

4 死锁检测和死锁恢复

系统并不试图阻止死锁的产生,而是允许死锁发生,当检测到死锁发生后,采取措施进行恢复。

4.1 每种类型一个资源的死锁检测

构造一张资源分配图,如果这张图包含了一个或一个以上的环,那么死锁就存在。在此环中的任何一个进程都是死锁进程。如果没有这样的环,系统就没有发生死锁。

4.2 每种类型多个资源的死锁检测

如果有多种相同的资源存在,就需要采用另一种方法来检测死锁。基于矩阵的算法来检测从P1 到Pn 这n个进程中的死锁。
假设资源的类型数为m,E1 代表资源类型1,E2 代表资源类型2,Ei 代表资源类型i(1≤i≤m)。E是现有资源向量(existing resource vector),代表每种已存在的资源总数。
死锁检测算法如下:
1)寻找一个没有标记的进程Pi ,对于它而言R矩阵的第i行向量小于或等于A。
2)如果找到了这样一个进程,那么将C矩阵的第i行向量加到A中,标记该进程,并转到第1步。
3)如果没有这样的进程,那么算法终止。
算法结束时,所有没有标记过的进程(如果存在的话)都是死锁进程。

4.3 从死锁中恢复

1).利用抢占恢复
在不通知原进程的情况下,将某一资源从一个进程强行取走给另一个进程使用。
2)利用回滚恢复
将该进程复位到一个更早的状态,那时它还没有取得所需的资源,接着就把这个资源分配给一个死锁进程。如果
复位后的进程试图重新获得对该资源的控制,它就必须一直等到该资源可用时为止。
3)通过杀死进程恢复
最直接也是最简单的解决死锁的方法是杀死一个或若干个进程。一种方法是杀掉环中的一个进程。另一种方法是选一个环外的进程作为牺牲品以释放该进程的资源。在使用这种方法时,选择一个要被杀死的进程要特别小心,它应该正好持有环中某些进程所需的资源。

5 死锁避免

不过在大多数系统中,一次只请求一个资源。系统必须能够判断分配资源是否安全,并且只能在保证安全的条件下分配资源。
1)资源轨迹图
2)安全状态和不安全状态
3)单个资源的银行家算法:银行家算法就是对每一个请求进行检查,检查如果满足这一请求是否会达到安全状态。若是,那么就满足该请求;若否,那么就推迟对这一请求的满足。为了看状态是否安全,银行家看他是否有足够的资源满足某一个客户。如果可以,那么这笔投资认为是能够收回的,并且接着检查最接近最大限额的一个客户,以此类推。如果所有投资最终都被收回,那么该状态是安全的,最初的请求可以批准。
4)多个资源的银行家算法
在这里插入图片描述
最右边的三个向量分别表示现有资源E、已分配资源P和可用资源A。由E可知系统中共有6台磁带机、3台绘图仪、4台打印机和2台CD-ROM驱动器。由P可知当前已分配了5台磁带机、3台绘图仪、2台打印机和2台CD-ROM驱动器。该向量可通过将左边矩阵的各列相加获得,可用资源向量可通过从现有资源中减去已分配资源获得。

检查一个状态是否安全的算法如下:
1)查找右边矩阵中是否有一行,其没有被满足的资源数均小于或等于A。如果不存在这样的行,那么系
统将会死锁,因为任何进程都无法运行结束(假定进程会一直占有资源直到它们终止为止)。
2)假若找到这样一行,那么可以假设它获得所需的资源并运行结束,将该进程标记为终止,并将其资源
加到向量A上。
3)重复以上两步,或者直到所有的进程都标记为终止,其初始状态是安全的;或者所有进程的资源需求
都得不到满足,此时就是发生了死锁。
如果在第1步中同时有若干进程均符合条件,那么不管挑选哪一个运行都没有关系,因为可用资源或者
会增多,或者至少保持不变。

该算法虽然很有意义但缺乏实用价值,因为很少有进程能够在运行前就知道其所需资源的最大值。而且进程数也不是固定的,往往在不断地变化(如新用户的登录或退出),况且原本可用的资源也可能突然间变成不可用(如磁带机可能会坏掉)。因此,在实际中,如果有,也只有极少的系统使用银行家算法来避免死锁。

6 死锁预防

死锁避免从本质上来说是不可能的,因为它需要获知未来的请求,而这些请求是不可知的。那么实际的系统又是如何避免死锁的呢?
1)破坏互斥条件
2)破坏占有和等待条件
3)破坏不可抢占条件
4 )破坏环路等待条件
消除环路等待有几种方法。一种是保证每一个进程在任何时刻只能占用一个资源,如果要请求另外一个资源,它必须先释放第一个资源。但假若进程正在把一个大文件从磁带机上读入并送到打印机打印,那么这种限制是不可接受的。另一种避免出现环路等待的方法是将所有资源统一编号。
在这里插入图片描述

7 其他问题

7.1 两阶段加锁

虽然在一般情况下避免死锁和预防死锁并不是很有希望,但是在一些特殊的应用方面,有很多卓越的专用算法。常用的方法是两阶段加锁(two-phase locking)。在第一阶段,进程试图对所有所需的记录进行加锁,一次锁一个记录。如果第一阶段加锁成功,就开始第二阶段,完成更新然后释放锁。在第一阶段并没有做实际的工作。

7.2 通信死锁

发生在通信系统中(比如说网络),即两个或两个以上进程利用发送信息来通信时。一种普遍的情形是进程A
向进程B发送请求信息,然后阻塞直至B回复。假设请求信息丢失,A将阻塞以等待回复,而B会阻塞等待一
个向其发送命令的请求,因此发生死锁。

7.3 活锁

进程总是一再消耗完分配给它们的CPU配额,但是没有进展也没有阻塞。因此,没有出现死锁现象(因为没有进程阻塞),但是从现象上看好像死锁发生了,这就是活锁(livelock)。

7.4 饥饿

进程无限期地等待不会被分配的资源,(该进程对资源的请求被无限期的推后,就像饿死了一样。)饥饿可以通过先来先服务资源分配策略来避免。在这种机制下,等待最久的进程会是下一个被调度的进程。随着时间的推移,所有进程都会变成最“老”的,因而,最终能够获得资源而完成。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值