资源是应用程序执行时所需要的全部硬件、软件和数据的集合。
死锁是指一个进程集合中每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么该进程集合就是死锁的。
资源管理的任务:资源管理模块的任务是解决资源分配的问题。它包含有:
- 资源数据结构的描述
- 确定资源分配原则和调度原则
- 执行资源分配
- 存取控制和安全保护
描述各类资源的最小分配单位的数据结构称为资源描述器(RD)
资源描述器描述了资源的特性和该资源的管理方式。
资源信息块(RIB)描述了:某类资源的请求者,可利用的资源该资源分配程序的地址
资源分配策略:
- 先请求先服务(FIFO):批处理系统在作业角度时采用FIFO策略
- 优先调度:根据优先级从高到低进行排列…优先级高的最先处理
- 针对设备特性的调度:
(1)移臂调度:在满足一个磁盘请求时,总是选取当前移动臂前进方向上最近的请求。
(2)旋转调度:选取读写头旋转方向上最近的请求。
移臂调度算法:
最短寻道时间优先(SSTF):总是从等待访问者中选出寻道时间最短的请求先执行。
采用最短寻道时间优先算法选择与当前磁头最近的那个请求可以减少寻道时间,因而缩短了为各访问者请求服务的平均时间,提高了效率。
扫描算法(SACN):有名电梯调度算法,磁头前进方向上最短查找时间优先算法。
资源分为两类:可抢占和不可抢占的
可抢占资源:可以从拥有它的进程中抢占而不会产生任何副作用,存储器就是一类可抢占资源。
不可抢占资源:是指在不引起相关的计算失败的情况下,无法把它从占有它的进程处抢占过来。
死锁规范定义:如果一个进程集合中每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么该进程集合就是死锁的。
产生死锁的原因是:系统能够提供的资源个数比请求该资源的进程数要少。当系统中两个或多个进程若因申请资源得不到满足而等待时,若各个进程都没有能力进一步执行,系统就发送死锁。
资源死锁的条件:
- 互斥条件:一段时间内,某资源只能由一个进程占用
- 占有和等待条件:请求或等待新资源时,不释放已经分配到的资源
- 不可抢占条件:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
- 环路等待条件:系统中有两个或两个以上的进程组成环路,环路中每个进程都在等待着下一个进程所占有的资源。
处理死锁的四种策略:
- 忽略该问题:
- 检测死锁并恢复
- 仔细对资源进行分配,避免死锁
- 破坏死锁的四个必要条件之一,防止死锁发生
忽略该问题:鸵鸟算法
如果死锁平均五年发生一次,而每个月系统都会因为硬件故障,编译器错误或者操作系统崩溃而崩溃一次,那么大多数工程师不会以性能损失和可用代价取防止死锁。
死锁的检测与恢复:抢占恢复,回滚恢复,杀死进程恢复
系统并不阻止死锁的产生,而是运行死锁产生,当检测到死锁发生后,采取措施恢复。
检测方法:矩阵向量的比较。
死锁避免:银行家算法
安全状态与不安全状态:
安全状态:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得
每一个进程进行完毕,则称该状态是安全的。
不安全状态:不是死锁,而是系统不能保证所有的进程都能完成。
银行家算法:对每一请求进行检查,如果满足这一请求后是否是到达安全状态,如果是,满足该请求,否则推迟对该请求的相应。
该算法虽然很有意义,但是缺乏实用价值,因为很少有进程在运行前就知道其所需要资源的最大值,而且进程数和资源数量也不是固定的。
死锁预防:
(1)破坏互斥条件:资源不被一个进程所独占,那么死锁肯定不会发生。
(2)破坏占有和等待条件:在开始执行前请求所需全部资源。如果所需全部资源可用,那么就将他们分配给这个进程,于是该进程肯定能够运行结束。如果有一个或多个资源正在被使用,那么就不进行分配,进程等待。
直接的问题是:很多进程直到运行才知道它需要多少资源,而且相比起来实际上银行家算法更为有效。
另一种方法是:当一个进程请求资源时,先释放其占用的所有资源,然后再尝试一次获得所需全部资源。
(3)破坏不可抢占:采用部分资源虚拟化的方式进行,例如打印机。
(4)破坏环路等待条件:资源编号,顺序获取(但是找不到令人满意的编号次序)
两阶段加锁:
第一阶段,进程试图对所有所需的记录进行加锁,一次锁住一个记录。
如果第一阶段成功,就开始第二阶段,更新完成后释放锁。
如果第一阶段某个进程需要的记录已经被加锁,那么该进程释放它所有的加锁记录,然后重新开始第一阶段。
通信死锁:
在一系列进程中,每个进程因为等等另外一个进程引发的事件而产生阻塞,这就是一种死锁。
普遍情形:进程A向进程B发送消息,然后进程阻塞直至进程B回复。假设请求信息丢失,A将阻塞以等待回复,而B会阻塞等待另一个向其发送的命令的请求,因此发生死锁。
解决办法:超时重传。
活锁:
两个资源,进程A请求1,进程B请求2,然后A不停的请求2,B不停的请求1,以后不管哪个进程运行,都不会有任何进展,但是也没有被阻塞。
从现象看死锁发生了,实际上没有出现死锁现象(因为没有进程阻塞)
饥饿:
在优先级调度中,高优先级先被调度,而低优先级永远得不到调度。
可以用先来先服务解决。