目标
了解死锁的原因,
死锁阻止 并发进程集完成它们的任务
提出许多不同的方法来防止或避免计算机系统中的死锁
僵局问题
一组阻塞的进程,每个进程都持有一个资源,并等待获取该集中另一个进程持有的资源
例如:
系统有两个磁盘驱动器
P1和P2各有一个磁盘驱动器,并且各需要一个磁盘驱动器。
信号量甲和乙,初始化为1
第一亲代
wait (A); wait(B) wait (B); wait(A)
系统模型
包括资源类型
cpu memeor io
每种资源类型实例
每个进程实例
请求
使用
释放
死锁表征
四个要素,缺一不可
互斥:一次只有一个进程可以使用一个资源
持有等待:至少持有一个资源的进程正在等待获取其他进程持有的额外资源
不可抢占:资源只能由持有它的进程在完成任务后主动释放
循环等待:如果一个进程需要的资源被占用,就一直等待,不会主动释放
资源分配图
一个资源可以有多个实例,线程去请求实例.一个资源的实例可以分配个不同的进程.
请求,和给实例,是又向的. 如果形成闭环,就有可能发生死锁
基本事实
如果图不包含循环,没有死锁
如果图形包含循环
如果每个资源类型只有一个实例,那么死锁
如果每个资源类型有几个实例,则有可能出现死锁
处理死锁的几种方法
确保系统永远不会进入死锁状态
允许系统进入死锁状态,然后修复死锁,
完全放任,假装死锁从来没有在系统中发生过;被大多数操作系统使用,包括UNIX
死锁预防
只需要破坏四个必要条件之一
限制提出请求的方式
互斥——共享资源不需要互斥;对于不可中断的资源必须保持(资源一般还是需要互斥的)
保持和等待——必须保证每当一个进程请求一个资源时,它不保持任何其他资源
要求进程在开始执行之前请求并分配所有资源,或者仅当进程没有资源时才允许进程请求资源
资源利用率低,可能有的线程长时间获取不到资源,饥饿
如果持有某些资源的进程请求另一个不能立即分配给它的资源,则释放当前持有的所有资源
抢占的资源被添加到进程正在等待的资源列表中
只有当进程可以重新获得它的旧资源以及它正在请求的新资源时,它才会重新启动
循环等待——强制所有资源类型的总顺序,并要求每个进程以递增的枚举顺序请求资源
避免死锁
要求系统具有一些额外的花销开始之前进行检验
最简单和最有用的模型要求每个进程声明它可能需要的每种类型的资源的最大数量
死锁避免算法动态检查资源分配状态,以确保永远不会出现循环等待情况
资源分配状态由可用和已分配资源的数量以及进程的最大需求来定义
安全状态
当进程请求可用资源时,系统必须决定立即分配是否会使系统处于安全状态
如果存在序列,系统处于安全状态< P1,P2,…,例如
对于每个项目接口,项目接口仍然可以请求的资源可以由当前可用资源减去所有项目接口持有的资源来满足
如果Pi资源需求不是立即可用的,那么Pi可以等待直到所有Pj都完成
当Pj完成时,Pi可以获得所需的资源,执行,返回分配的资源,并终止
当Pi终止时,Pi +1可以获得自己需要的资源,以此类推
基本事实
如果系统处于安全状态,既没有死锁
如果系统处于不安全状态,有可能出现死锁
避免或确保系统永远不会进入不安全状态。
回避算法
声明边缘Pi Rj指示进程Pi可以请求资源rj;由虚线表示
当进程请求资源时,声明边缘转换为请求边缘
当资源分配给流程时,请求边缘转换为分配边缘
当一个进程释放一个资源时,分配边重新转换为声明边缘
必须在系统中先检查要求资源是否可用是否形成闭环
资源分配图算法
假设过程P;请求资源R;
只有当将请求边转换为分配边不会导致资源分配图中形成一个循环时,请求才能被授予
银行家算法
多个实例
每个进程必须实现声明最大限度的使用
当一个进程请求一个资源时,它可能不得不等待
当一个进程获得所有资源时,它必须在有限的时间内返回它们
银行家算法的数据结构
设n =进程数,m =资源类型数。
可用:长度为m的向量。如果可用[j] = k,则有k个资源类型Rj的实例可用
Max: n x m矩阵。如果Max [i,j] = k,那么进程Pi最多可以请求k个资源类型Rj的实例
分配:n x m矩阵。如果分配[i,j] = k,那么Pi当前被分配了Rj的k个实例
需要:n x m矩阵。如果需要[i,j] = k,那么Pi可能还需要k个Rj的实例来完成它的任务
需要[i,j] =最大[i,j]–分配[i,j]
安全算法
设Work和Finish分别是长度为m和n的向量。
初始化:
Work =Available
Finish[i]=false for i = 0,1,…, n - 1
…
过程pi的资源请求算法
Requesti =进程Pi的请求向量。
如果Requesti [j] = k,那么进程Pi需要资源类型Rj的k个实例
1.如果我要求,需要我去第二步。否则,引发错误条件,因为进程已超过其最大要求
2.如果请求可用,请转到步骤3。否则Pi必须等待,因为资源不可用
3.通过如下修改状态,假装将请求的资源分配给Pi:
可用=可用-请求;
allocation I = allocation I+Requesti;
Needi = Needi–Requesti;
如果安全the资源被分配给Pi
如果不安全,Pi必须等待,旧的资源分配状态恢复
A (10个实例)、B(5个实例)和C (7个实例)时间T0的快照:
死锁检测
允许系统进入死锁状态
检测算法
恢复机制
每种资源类型的单一实例
维护等待图
节点是流程
Pi Pj如果Pi在等Pj
定期调用算法,在图形中搜索循环。如果有循环,就存在死锁
检测图中循环的算法需要n2次运算,其中n是图中顶点的数量
资源类型的几个实例
可用:长度为m的向量表示每种类型的可用资源数量。
分配:n x m矩阵定义了当前分配给每个进程的每种类型的资源数量。
请求:n x m矩阵表示每个进程的当前请求。如果Request [i,j] = k,那么进程Pi请求更多的资源类型Rj的实例。
检测算法
设Work和Finish为长度为m和n的向量,分别初始化:
算法需要一系列操作来检测系统是否处于
僵持状态
检测-算法使用
何时以及多久调用一次取决于:
死锁发生的频率有多高?
需要回滚多少个进程?
每个不相交循环的
如果任意调用检测算法,那么资源图中可能会有许多循环,因此我们无法判断许多死锁进程中的哪一个“导致”了死锁
从死锁中恢复:进程终止
中止所有死锁进程
一次中止一个进程,直到死锁循环被消除
应该按哪个顺序选择中止?
流程的优先级
计算过程需要多长时间,还要多长时间才能完成
流程使用的资源
资源流程需要完成
需要终止多少流程?流程是交互式的还是批量的?
从死锁中恢复
选择受害者-最小化成本
回滚
返回到某个安全状态,重新启动该状态的进程
饥饿
相同的过程可能总是被选择为受害者
包括成本因素中的回滚数量