《现代操作系统》读书笔记---死锁篇

《现代操作系统》读书笔记—死锁篇

标签: 读书笔记 校招 操作系统 面试


资源

可剥夺资源:是指虽然资源占有者进程需要使用该资源,但另一个进程可以强行把该资源从占有者进程处剥夺来归自己使用。
不可剥夺资源:是指除占有者进程不再需要使用该资源而主动释放资源,其他进程不得在占有者进程使用资源过程中强行剥夺。

死锁概述

死锁定义

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

发生死锁的必要条件

  • 互斥条件:一个进程要么已经分配给了一个进程,要么就是可用的.
  • 不剥夺条件:已经分配给一个进程的资源不能强制性的被抢占,它只能被占有它的资源显式的释放.
  • 请求与保持条件:已经得到了某个资源的进程可以再请求其他新的资源.
  • 环路等待条件:死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路的每个进程都在等待下一个进程所占有的资源.
    要产生死锁,这4个条件缺一不可,因此可以通过破坏其中的一个或几个条件来避免死锁的产生。

死锁处理的四种方法

目前用于处理死锁的方法主要有以下4种:
1. 鸵鸟算法:指像鸵鸟一样对死锁视而不见,即不理睬死锁。
2. 预防死锁:通过设置某些限制条件,去破坏产生死锁的4个必要条件中的一个或几个来预防死锁的产生。
3. 避免死锁:在资源的动态分配过程中,用某种方法防止系统进入不安全状态,从而避免死锁的产生。
4. 检测及解除死锁:通过系统的检测机构及时地检测出死锁的发生,然后采取某种措施解除死锁。

鸵鸟算法

鸵鸟算法的思路就是把头埋在沙子里面,不管问题的发生.
当死锁发生的频率足够低的时候,这种方法就是可以接受的.考虑一个个人PC机,如果一个月出现一次死锁,那么就可以直接重启就好了.

死锁检测和恢复

在这种方法中,系统并不阻止死锁的发生.而是允许死锁发生,当检测到死锁发生后,采取措施进行恢复.本节我们考虑检测死锁的几种算法和几种处理的办法.

死锁检测

资源分配图

进程的死锁问题可以用有向图更加准确而形象地描述,这种有向图称为系统资源分配图。
其中方框表示资源,圆圈表示进程.方框指向进程的箭头表示资源被进程所占用

死锁定理

可以用简化资源分配图的方法来检测系统状态S是否是死锁状态。简化方法如下:

  • 首先,在资源分配图中,找出一个既不阻塞又非孤立的进程节点Pi。因进程Pi获得了所需要的全部资源,它能继续运行直到完成,然后释放其占有的所有资源;
  • 其次,进程Pi释放资源后,可以唤醒因等待这些资源而阻塞的进程,原来阻塞的进程可能变为非阻塞进程;
  • 最后,重复前两步的简化过程后,若能消去图中所有边,使所有进程成为孤立节点,则称该图是可完全简化的;若不能通过任何过程使该图完全简化,则称该图是不可完全简化的。

S为死锁状态的条件是:当且仅当S状态的资源分配图是不可完全简化的,该定理称为死锁定理。

死锁检测算法

每种类型一个资源的死锁检测
对于上图中的死锁,可以用如下方法检测:
1. 对图中每一个节点N,将N作为起始点执行下面5个步骤.
2. 将L初始化为空表,并清除所有的有向边标记
3. 将当前节点添加到L的尾部,并检测该节点是否在L中已出现两次.如果是,那么该图包含了一个环,算法结束.
4. 从给定的节点开始,检测是否存在没有标记的从该节点出发的弧(有向边).如果存在做第五步,如果不存在第六步
5. 随机选取一条没有标记的从该节点出发的弧,标记它.然后顺着这条弧线找到新的当前节点,返回到第三步.
6. 如果这一个节点是起始节点,那么表明该图不存在任何环,算法结束.否则意味着我们走入了死胡同,所以需要移走该节点,返回前一个节点,即当前节点前一个节点,并将它作为新的当前节点,同时转到第三步.

这一算法是依次将每一个节点作为一棵树的根节点,并进行深度优先搜索.如果再次碰到已经遇到过的节点,那么就算找到一个环.如果从任何给定节点出发的弧都被穷举了,那么就回溯到前面的节点,如果回溯到根并不能再深入下去,那么从当前节点触发的子图中就不包含任何环.如果对每个节点都是如此,那么整个图就不存在环,也就是说系统并不存在死锁.

死锁解除

一旦检测出系统中出现了死锁,就应使陷入死锁的进程从死锁状态中解脱出来。常用的解除死锁方法有两种:

  • 剥夺资源:从其他进程中抢占足够的资源给死锁的进程以解除其死锁状态;
  • 撤销进程:撤销一些进程,直到有足够的资源分配给其他进程,解除死锁状态。

死锁避免

在避免死锁的办法中,所施加的限制条件较弱,有可能获得较好的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终处于安全状态,便可以避免死锁的发生。

安全状态与不安全状态

安全状态:按某方案分配资源系统一定不会进入死锁。

不安全状态:按某方案分配资源,系统有可能进入死锁。

安全状态一定不会导致死锁,不安全状态不一定会导致死锁,但是有可能导致死锁。

银行家算法

银行家算法中使用的数据结构如下:

  • 可利用资源向量Available;
  • 最大需求矩阵Max;
  • 分配矩阵Allocation;
  • 需求矩阵Need。

“矩阵三兄弟”具有如下关系:Need[i][j]=Max[i][j]-Allocation[i][j];
银行家算法的流程图如下:

死锁预防

死锁避免从本质上说是不可能的,因为它需要获知未来的请求,而这些请求是不可知的.那么实际的系统是怎么避免死锁的呢.
主要是破坏死锁的四个必要条件.
* 互斥条件
为了破坏互斥条件,就要允许多个进程同时访问资源。但是这会受到资源本身固有特性的限制,有些资源根本不能同时访问,只能互斥访问,如打印机就不允许多个进程在其运行期间交替打印数据,只能互斥使用。由此看来,通过破坏互斥条件来防止死锁的发生是不大可能的。
* 不剥夺条件
为了破坏不剥夺条件,可以制定这样的策略:对于一个已经获得了某些资源的进程,若新的资源请求不能立即得到满足,则它必须释放所有已经获得的资源,以后需要资源时再重新申请。
* 请求与保持条件
为了破坏请求与保持条件,可以采用预先静态分配方法。预先静态分配法要求进程在其运行之前一次性申请它所需要的全部资源,在它的资源未满足前,不把它投入运行。一旦投入运行后,这些资源就一直归它所有,也不再提出其他资源请求,这样就可以保证系统不会发生死锁。
* 环路等待条件
为了破坏环路等待条件,可以采用有序资源分配法。有序资源分配法是将系统中的所有资源都按类型赋予一个编号(例如打印机为1,磁带机为2),要求每一个进程均严格按照编号递增的次序请求资源,同类资源一次申请完。

其他问题

两阶段加锁

虽然在一般情况下预防死锁和避免死锁并不是很有希望,但是在一些特殊的应用方面,有很多卓越的专用算法.
例如数据库中常用的办法是两阶段加锁.在第一阶段,进程试图对所有所需的记录进行加锁,一次锁一个记录.如果第一阶段成功,就开始第二阶段,完成更新然后释放锁.在第一阶段并没有做实际的工作.
如果在第一阶段某个进程需要的记录已经被加锁,那么该进程释放它所有的加锁记录,然后重新开始第一阶段.从某种意义上说,这种方法类似于提前或者至少是未实施一些不可逆操作之前请求所有的资源.在两阶段加锁的一些版本中,如果在第一阶段碰到了已经加锁的记录,并不会释放锁然后重新开始,这就可能导致死锁.
但是在一般情况中,这种策略并不通用,因为,让一个进程重新开始是那么现实的.

活锁

在某种情形下,轮询可用于进入临界区或者获取资源.
在下面这段代码中,

void process_A(void){
    enter_region(resource1);
    enter_region(resource2);
    use_both_resources();
    leave_region();
    leave_region(resource2);
    leave_region(resource1);
}
void process_B(void){
    enter_region(resource2);
    enter_region(resource1);
    use_both_resources();
    leave_region();
    leave_region(resource1);
    leave_region(resource2);
}

如果A进程得到资源1,然后B得到2,然后它们就会一直轮询下去,虽然没有死锁现象(进程没有阻塞),但是死锁确实发生了.这就是活锁;

饥饿

在动态运行的系统中,在任何时刻都有可能请求资源,这就需要一些策略来决定在什么时候谁获得资源.虽然这个策略表面上很有道理,但是依然有可能使一些进程永远得不到服务,虽然它们并不是死锁进程.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值