d4d1de8747e53ca0d60232de0ff87475.ppt
- Количество слайдов: 62
第五章 死锁与饥饿 n 死锁: indefinite wait. l n 可察觉 饥饿: not necessarily in wait state. l ? n 死锁和饥饿都是由于进程竞争资源而引起 的.
5. 1 死锁的概念 例子: r 1 和 r 2为可再用资源; P 1: apply for r 1; P 2: apply for r 2; . . . 1 apply for r 2; . . . 2 apply for r 1; . . . return r 2;
死锁定义 n 一组进程中的每一个进程,均无限期地等待此 组进程中某个其他进程占有的,因而永远无法 得到的资源,这种现象称为进程死锁。 n 定义死锁时刻: n 无限等待发生时; n 等待发生前(已注定死锁)。
由定义得到的结论 n 几个有用的结论: 参与死琐的进程至少有二个; n 每个参与死锁的进程均等待资源; n 参与死锁的进程中至少有两个进程占有资源; n 死锁进程是系统中当前进程集合的一个子集。 n
5. 2 死锁类型 1. 竞争资源引起的死锁 (1)不同种资源 W: 直行 A B C E:左转 D S:左转
5. 2 死锁类型 1. 竞争资源引起的死锁 (1)不同种资源 W: 直行 E S W E:左转 S S:左转
5. 2 死锁类型 1. 竞争资源引起的死锁 (1)不同种资源 W: 直行 E E W E:左转 S S:左转
5. 2 死锁类型 (2)同种资源 4台打印机,申请: a, 释放 a P 1: a a a a P 2: a a
5. 2 死锁类型(Cont. ) 2. 进程通讯引起的死锁 P 1:receive(P 2, M 1); P 2: receive(P 3, M 2); P 3: receive(P 1, M 3); 3. 其它原因引起的死锁 1. After you / after you
5. 3 死锁的条件 n Coffman条件(必要条件) 资源独占(mutual exclusion) n 不可抢占(non preemption) n 保持申请(hold-while-applying) n 循环等待(circular wait) n n 当每类资源只有一个实例时,充要条件。 n 破坏上述任意一个条件可以消除死锁。
5. 4 死锁的处理 prevention)-静态 n 死锁避免(deadlock avoidance)--动态 n 死锁检测(deadlock detection) n 死锁恢复(deadlock recovery) n 死锁预防(deadlock
5. 5 资源分配图 定义: G=(V, E), V=P R, P={p 1, p 2, …, pn}, R={r 1, r 2, …, rm}, E={(pi, rj)} {(rj, pi)}, pi P, rj R. 申请边(pi, rj): pi申请rj; 分配边(rj, pi): rj分配pi; 图示:进程: 资源: 申请边:由进程到资源类; 分配边:由资源实例到进程。
5. 5 资源分配图 n 申请:pi申请rj中的一个资源实例,由pi向 rj画一条申请边,如可满足,改为分配边。 n 释放:去掉分配边。
例子(无环路,无死锁) 例1. P={p 1, p 2, p 3}, R={r 1(1), r 2(2), r 3(1), r 4(3)} E={(p 1, r 1), (p 2, r 3), (r 1, p 2), (r 2, p 1), (r 2, p 2), (r 3, p 3), (r 4, P 3)} r 1 r 3 p 1 p 3 p 2 r 4
例子(有环路,有死锁) 增加边(p 3, r 2) r 1 r 3 p 1 p 3 p 2 r 4
例子(有环路,无死锁) p 1 p 2 r 1 p 3 p 4 r 2
例子(有环路,无死锁) p 1 p 2 r 1 p 3 p 4 P 2释放占有资源r 1, 分给P 1, (p 1, r 1)改为(r 1, p 1) r 2
5. 5. 2 资源分配图的约简 寻找一个非孤立且没有请求边的节点 pi, 若无算法结束 2. 去除pi的所有分配边使其成为一个孤立 节点; 3. 寻找所有请求边都可满足的进程pj, 将 pj的所有请求边全部改为分配边; 4. 转步骤 1 1.
死锁定理 n 若算法结束时, 所有节点均为孤点, 则称资 源分配图是完全可约简的, 否则称为不可 完全约简的. n 死锁定理: n S为死锁状态的充分必要条件是S的资源分配 图不可完全约简.
5. 6 死锁预防 n 对进程有关资源的活动加限制,所有进程 遵循这种限制,即可保证没有死锁发生。 优点:简单,系统不需要做什么。 n 缺点:对进程的约束,违反约束仍可能死锁。 n n 预防方法: n 预先分配法; n 有序分配法。
5. 6. 1 预先分配法 n 进程:运行前申请所需全部资源; n 系统: 能够满足,全部分配, n 否则,一个也不分配。 n n 破坏“hold-and-wait”条件 n 缺点: 资源利用效率低; n 一次提出申请困难。 n
5. 6. 2 有序分配法 资源集:R={r 1, r 2, …, rn} 函数:F:R N 例如:R={scanner, tape, printer} F(scanner)=1; F(tape)=2; F(printer)=3; 申请次序 r 1 r 2 . . . rk . . . rm 进程pi可以申请资源rj中的实例 rl, pi当前占有rl, F(rl) F(rj)
5. 6. 2 有序分配法 证明无死锁(deadlock free): 反证,假定死锁 时刻t 1: p 1无限等待rk 1中的资源实例,被p 2占有; t 2: p 2无限等待rk 2中的资源实例,被p 3占有; … tn: pn无限等待rkn中的资源实例,被p 1占有; 根据有序申请假设: F(rk 1)<F(rk 2)<…<F(rkn)<F(rk 1) 矛盾。
5. 6. 2 有序分配法 n 优点 n 与预先分配相比, 资源利用率提高. n 缺点 资源编号困难; n 为保持按序申请, 某些暂时不用的资源也需提 前申请, 牺牲资源利用率. n
例子 A W: 直行 B C E:左转 D S:左转 死锁的可能性:情形 1,情形 2 资源编号:F(D)=1; F(B)=2; F(A)=3; F(C)=4; Var S 1, S 2, S 3, S 4: semaphore; (1, 1, 1, 1)
例子 Procedure S: P(S 1); 驶入D; P(S 2); 驶入B; V(S 1); P(S 3); 驶入A; V(S 2); 驶出A; V(S 3) Procedure E: P(S 2); 驶入B; P(S 3); 驶入A; V(S 2); P(S 4); 驶入C; V(S 3); 驶出C; V(S 4); Procedure W: P(S 1); P(S 4); 驶入C; 驶入D; V(S 4); 驶出D; V(S 1);
例子 COBEGIN S 1: S; … ; Sm: S; E 1: E; … ; En: E; W 1: W; . . . ; Wo: W COEND;
5. 7 死锁避免 安全 可满足请求 检测 不安全 分配 不分配 系统处于安全状态:存在安全进程序列<p 1, p 2, …, pn>安全,p 1, p 2, …, pn可依次进行 完。 安全 死锁 不安全
银行家算法(Cont. ) Banker’s algorithm, E. W. Dijkstra. 进程:事先申明所需资源最大量(并不分配) Claim=Max 系统:对每个可满足的资源申请命令进行安全性检查。 安全, 分配; 不安全: 不分配 P={p 1, p 2, …, pn}; R={r 1, r 2, …, rm};
银行家算法(Cont. ) 数据结构: Available: array[1. . m]of integer; //系统可用资源 Claim: array[1. . n, 1. . m]of integer; //进程最大需求 Allocation: array[1. . n, 1. . m]of integer; Need: array[1. . n, 1. . m]of integer; Request: array[1. . n, 1. . m]of integer; 临时变量: Work: array[1. . m]of integer; Finish: array[1. . n]of boolean; //当前分配 //尚需资源 //当前请求
银行家算法(Cont. ) 设X, Y为下标1. . l的一维数组: X Y j (1 j l), X[j] Y[j] X: =Y j (1 j l), X[j]: =Y[j] X: =c j (1 j l), X[j]: =c X±Y j (1 j l), X[j]±Y[j]
资源分配 Pi请求资源 T F Request[I] Need[I] Request[I] Available 不满足,等待 T 确认,pi继续 T F 请求超量,错返 Available: =Available-Request[I] Allocation[I]: =Allocation[I]+Request[I] Need[I]: =Need[I]-Request[I] 安全 F Available: =Available+Request[I] Allocation[I]: =Allocation[I]Request[I] Need[I]: =Need[I]+Request[I]
安全性检测算法 Work: =Available; Finish: =false; T 有满足条件的j: Finish[j]=false Need[j] Work F T Finish[j]=true; Work: =Work+Allocation [j] 安全 F j , finish[j]=true 不安全
银行家算法例子 R={A(10), B(5), C(7)} P 0: p 1: p 2: p 3: p 4: Claim A B C 7 5 3 3 2 2 9 0 2 2 4 3 3 P={p 0, p 1, p 2, p 3, p 4} Allocation Need A B C 0 1 0 7 4 3 2 0 0 1 2 2 3 0 2 6 0 0 2 1 1 0 0 2 4 3 1 Available A B C 3 3 2 安全进程序列:<p 1, p 3, p 4, p 2, p 0> p 1请求:Request[1]=(1, 0, 2) Work Finish A B C
银行家算法例子 假定分配: P 0: p 1: p 2: p 3: p 4: Claim A B C 7 5 3 3 2 2 9 0 2 2 4 3 3 Allocation A B C 0 1 0 3 0 2 2 1 1 0 0 2 A 7 0 6 0 4 Need B C 4 3 2 0 0 0 1 1 3 1 Available Work Finish A B C 2 3 0 安全进程序列:<p 1, p 3, p 4, p 0, p 2> p 4请求:Request[4]=(3, 3, 0), 不能满足,等待; p 0请求:Request[0]=(0, 2, 0), 不安全,取消分配,等待。
银行家算法的保守性 例子:R={A, B}, 申请a, b; 释放a, b P={p 1, p 2}, p 1: a b; p 2: b b b a a b Claim A B p 1: 1 1 p 2: 1 1 Allocation A B 0 0 Need A B 1 1 Available A B 1 1 Request[1]=(1, 0), 安全,分配。 Work A B Finish
银行家算法的保守性 分配后: Claim Allocation A B p 1: 1 1 1 0 p 2: 1 1 0 0 Need A B 0 1 1 1 Available Work Finish A B 0 1 Request[2]=(0, 1), 不安全,不分配,(分配不导致死锁)
讨论 Remarks 1: 银行家算法要求条件:进程所需资源最大量, 这个信息 对于充要性分析是不够的。 Remarks 2: 假设:进程预先给出有关资源的命令序列,则可以给出 死锁避免的充要性算法,复杂度(NP Complete)。 Remarks 3: 预先给出进程有关资源的命令序列是困难的(程序的分枝 和循环)。
5. 8 死锁的检测 数据结构: Available: array[1. . m]of integer; Allocation: array[1. . n, 1. . m]of integer; Request: array[1. . n, 1. . m]of integer; 临时变量: Work: array[1. . m]of integer; Finish: array[1. . n]of Boolean;
5. 8. 1 死锁检测算法 Work: =Available; Finish: =false; T Finish[i]=true; Finish[I]=true for allocation[I]=0 有满足条件的i: F Finish[i]=false F Request[i] Work T i , finish[i]=true Work: =Work+Allocation[i ] 无死锁 死锁
Remarks 1. 上述算法可以检测到参与死锁的全部进程,包括占有资 源和不占有资源的进程。 2. 如果希望只检测占有资源的进程,初始化时: Finish[i]=true, for Allocation[I]=0
死锁例子 例子:R={A(7), B(2), C(6)}; P={p 0, p 1, p 2, p 3, p 4} Allocation A B C p 0: 0 1 0 p 1: 2 0 0 p 2: 3 0 3 p 3: 2 1 1 p 4: 0 0 2 Request A B C 0 0 0 2 0 0 0 1 0 0 2 Available A B C 0 0 0 Work Finish A B C 未死锁。 此时,Request[2]=(0, 0, 1), 死锁,参与死锁进程 {p 1, p 2, p 3, p 4}
5. 8. 2 死锁检测时刻 考虑因素: 死锁发生频度; 死锁影响进程。 1. 等待时检测: 发现早,恢复代价小,开销大(overhead)。 2. 定时检测: 3. 资源(eg. CPU)利用率下降时检测。
5. 9 死锁的恢复 1. 重新启动 简单,代价大,涉及未参与死锁的进程。 2. 终止进程(process termination) 环路上占有资源的进程。 (1) 一次性全部终止;(2) 逐步终止(优先级,代价函数) 3. 剥夺资源(resource preemption)+进程回退(rollback) (1) select a victim;(2) rollback. 问题: (1) 保存snapshot代价大;(2) 消除影响困难; (3) starvation.
5. 10 鸵鸟算法 n 视而不见 n Pro: l 程师观点(考虑死锁发生的频率, 危害, 处理代价) l l n Cont: l 数学家观点 l n 死锁发生频率<其它故障引起的系统瘫痪的频率 死锁处理constant overhead > 危害 必须处理, 无论代价如何 目前系统实际如此 n Eg. UNIX proc结构(50 and up)
5. 11 有关问题的讨论 n 关于充要性算法 n 已知进程关于资源活动序列 l n n 复杂度高(NP Complete) 生灭资源问题 n n n 困难: 程序中的分枝与循环 消息 消耗性资源与可重用资源并存 关于两阶段封锁 n 增长阶段有可能死锁
5. 12 饥饿与活锁 饥饿(starvation):当等待时间给进程推进和响 应带来明显影响时, 称发生了进程饥饿. 饥饿到一 定程度的进程所赋予的使命即使完成也不再具 有实际意义时称该进程被饿死(starved to death). n 没有时间上界的等待 n n 排队等待 忙式等待条件下发生的饥饿, 称为活锁(live lock).
死锁与饥饿 n 饥饿 vs 死锁 死锁进程处于等待状态,忙式等待的进程并 非处于等待状态, 但却可能被饿死; n 死锁进程等待永远不会释放的资源, 饿死进程 等待可能被释放, 但却不会分给自己的资源, 其 等待时间没有上界; n 死锁一定发生了循环等待, 饿死不然; n 死锁至少涉及两个进程, 饿死进程可能只有一 个. n
5. 13 死锁的例子 过河问题: 水 流 West W-E 1 2 … n-1 n Deadlock prevention: one direction at any time. East E-W
过河问题 Var west_crossing, east_crossing: integer; (0, 0) west_wait, east_wait: integer; (0, 0); wq, eq: semaphore; mutex: semaphore; 西面过河者活动: P(mutex); If east_crossing>0 Then Begin west_wait: =west_wait+1; V(mutex); P(wq) End; Else Begin west_crossing: =west_crossing+1;
过河问题 V(mutex) End; 过河; P(mutex); west_crossing: =west_crossing-1; If west_crossing=0 Then While east_wait >0 Do Begin east_wait: =east_wait-1; east_crossing: =east_crossing+1; V(eq); End; V(mutex);
过河问题 东面过河者活动: P(mutex); If west_crossing>0 Then Begin east_wait: =east_wait+1; V(mutex); P(eq) End Else Begin east_crossing: =east_crossing+1; V(mutex) End;
过河问题 过河; P(mutex); east_crossing: =east_crossing-1; If east_crossing=0 Then While west_wait >0 Do Begin west_wait: =west_wait-1; west_crossing: =west_crossing+1; V(wq); End; V(mutex);
思考问题 n 对于过河问题,考虑一个没有饿死情况的 解法。
例2. 过河问题(2) 水 流 East West 8 1 -2 -3 -4 -6 -5 1 7 2 6 3 5 4 要求: (1)无死锁; (2)无饿死; (3)并行度高。 5 -6 -7 -8 -2 -1
Var S, s 1, s 2, s 3, s 4, s 5, s 6, s 7, s 8: semaphore; E W: (5, 1, W E: 1, 1, 1, 1) P(S); V(s 3); P(s 5); P(s 1); P(s 5); 走到 5; 走到 1; P(s 6); P(s 2); 走到 6; 走到 2; V(s 4); V(s 5); V(s 1); 走到 5; P(s 7); P(s 3); V(s 6); 走到 7; 走到 3; 走到E; V(s 6); V(s 2); V(s 5); P(s 8); P(s 4); V(S); 走到 8; 走到 4; V(s 7); P(s 1); P(s 2); 走到 2; V(s 8); 走到 1; V(s 2); 走到W; V(s 1); V(S);
5. 14 简单组合资源死锁的静态分析 条件:已知各个进程有关资源的活动序列; 判断:有无死锁可能性。 步骤 1:以每个进程占有资源,申请资源作为一个状态, 记作:(pi:aj:ak 1, …, akn)=(进程:请求:占有); 步骤 2:以每个状态为一个节点; 步骤 3:如s 1所申请资源为s 2所占有,则由s 1向s 2画一有向 弧(相同进程间不画); 步骤 4:找出所有环路; 步骤 5:判断环路上状态是否能同时到达,如是有死锁可能 性,否则无死锁可能性。 (1)环路中有相同进程,不能到达; (2)环路中有相同被占有资源,不能到达。
死锁分析例子 R={A,B,C,D,E,F,G} p 1:c d c a b d a b p 2:d e d b f e b f p 3:c e e f a (p 1: d: c ) (p 2: e: d ) (p 3: e: c ) (p 1: a: d ) (p 2: b: e ) (p 3: f: c) (p 1: b: da ) (p 2: f: eb) (p 3: a: cf)
死锁分析例子 R={A,B,C,D,E,F,G} p 1:c d c a b d a b p 2:d e d b f e b f p 3:c e e f a (p 1: d: c ) (p 2: e: d ) (p 3: e: c ) (p 1: a: d ) (p 2: b: e ) (p 3: f: c) (p 1: b: da ) (p 2: f: eb) (p 3: a: cf)
死锁分析例子 p 1:c d c a b d a b p 1: p 2:d e d b f e b f p 2: p 3:c e e f a 2 a pn: 1 证明:线 1不可达; 反证:假定线 1可达,则线 2可达。 p 2先于p 1; p 3先于p 2; p 1先于p 3, 矛盾。 …
5. 15 同种组合资源死锁的必要条件 M:资源数量 N:使用该类资源进程的数量 :所有进程所需要该类资源的总量 假定死锁,n个进程参与了死锁(2 n N) 参与死锁的进程所需资源的总量 M+n 未参与死锁进程所需资源的总量 N-n 所有进程所需资源的总量 M+n+N-n=M+N 当 <M+N时,一定没有死锁; 当 M+N时,至少有一个交叉有死锁。
例子 例1. M=15; N=4;P 1(4); P 2(6); P 3(1); P 4(7) =4+6+1+7=18<M+N=19 无死锁可能性。 例2. M=15; N=4;P 1(5); P 2(6); P 3(1); P 4(7) =5+6+1+7=19 M+N=19 有死锁可能性。死锁情况: P 1:a a a P 2:a a a P 3:a P 4:a a a a
d4d1de8747e53ca0d60232de0ff87475.ppt