死锁
一组相互竞争系统资源或进行通信的进程间的“永久”阻塞,涉及两个或多个进程之间对资源需求的冲突。
资源分配图
进程请求资源(其中黑色圆圈表示资源数,n个黑圆表示该资源有n个):
进程占有资源
将第一个图转化为资源分配图:
形成封闭的进程链,由于每个进程都占有链中下一个进程所需要的资源(进程2占有进程1所需要的资源B),也就形成循环等待
死锁的条件
1 互斥
一个资源一次只能被一个进程使用,其他进程不能访问已分配给其他进程的资源。
(资源A被进程1占用时,进程2不能访问资源A)
2 占有且等待
一个进程等待其他进程释放资源时,会继续占有已经分配的资源
(进程2等待进程1释放资源A,在等待期间会一直占有资源B)
3 不可抢占
不能强行抢占其他进程已占有的资源
(进程2不可以抢进程1的资源A,只能乖乖等它释放)
4 循环等待
存在一个封闭的进程链,使得每个进程至少占有此链中下一个进程所需要的一个资源
(前三个为必要不充分条件)
死锁预防(打破四个条件之一)
间接的死锁预防:防止前三个条件必要条件中之一
直接的死锁预防:防止循环等待的发生
1 防止互斥
这是不可能的
2 防止占有且等待
进程要不一次性请求完所有需要的资源,要不阻塞(一个资源都不获取)直到满足其请求的条件。
方法低效:
1.进程可能会长时间阻塞,部分不需要同时使用多种资源的进程也会阻塞
如进程2需要资源A、B,资源A被占有,则进程2被阻塞直到资源A被释放。若进程2目前只需要资源B完成部分工作,此时它仍然会被阻塞。
2.分配给一个进程的资源可能会长期不被使用,导致该资源不能被其他进程使用
进程2请求到了资源A、B,但目前进程2只使用B,导致A有长期的空闲时间,同时进程1页被一直阻塞
存在问题:
一个进程不会事先知道所需要的资源
3 防止不可抢占
方法1:占有某些资源的进程进一步请求资源时被拒,则释放其已经占有的资源
方法2:进程1需要一个被进程2占用的资源时,操作系统帮进程1将该资源抢占(要求进程优先级不同)
以上方法在资源状态可以容易保存和恢复的情况下才实用
4 防止循环等待
定义资源类型的线性顺序,进程只能按顺序请求资源。如进程P需要资源1、2、3(该数字为资源编号),则要按照123的顺序请求。举例:
进程P占有资源1,请求资源3;进程Q占有资源3,请求资源1;因此导致死锁。但按照顺序请求,进程Q会先请求资源1,所以不会出现已经占有资源3的情况。
方法同样低效
死锁避免
允许三个必要条件,通过判断是否导致死锁来作出选择。
方法1:如果一个进程的请求会导致死锁,则不启动
方法2:如果一个进程增加的资源请求会导致死锁,则不允许分配
进程拒绝启动
只有对任何资源,都满足所有当前进程的最大请求量加上新的进程请求时,才启动新的进程。如资源1有三个,进程A、B各请求1个,新进程C请求2个,则拒绝启动进程C。
资源拒绝分配
资源拒绝分配策略——银行家算法
- 向量Resource表示系统中每种资源的总量
- 向量Available表示未分配给进程的每种资源的总量
- 矩阵Claim中Cij表示进程i对资源j的需求
- 矩阵Allocation中Aij表示进程i当前获得资源j的数量
策略就是在四个进程中找出一个安全的运行序列,让一个进程继续获取资源且完成后释放资源,再让下一个进程获取资源且完成后释放资源......
因此先由P2请求剩余需要的资源,结束后释放资源
然后再找满足的进程如P1或P4......
故其安全序列为P2 P1 P3 P4(序列不唯一,能满足就好)
死锁恢复
- 取消所有死锁进程(操作系统最常采用方法)
- 连续取消死锁进程直到不再死锁(每次取消,要检测是否仍死锁)
- 连续抢占资源直到不再死锁(每次取消,要检测是否仍死锁)
- 把死锁回滚到之前的检查点并重新启动所有进程(要求系统中构造回滚和重启机制)