目录
4.死锁探测(Deadlock Detection) & 死锁恢复(Deadlock Recovery)
5.1 Mutual Exclusion Condition
5.4 The Circular Wait Condition
1.资源(Resources)
概述:资源可以是任何被单个进程在任何时刻使用的东西,当进程被授予对设备、文件等的独占访问权时,可能会发生死锁
资源类型:CPU周期,内存空间,I/O设备等
资源种类:
-
可重用的资源:
-
被进程使用后不被消耗,获取资源释放后给其他进程重用
-
例如:CPU、内存、磁盘空间、I/O设备、文件、数据库,信号量
-
-
可消耗的资源:
-
由进程创建和销毁,资源在被使用后停止存在,因此不会被释放
-
例如消息、信息缓冲区、中断
-
-
抢占式资源:
-
能从一个过程中拿走而没有不良影响
-
例如:CPU,内存
-
没有死锁
-
-
非抢占式资源:
-
不能从当前所有者被拿走,不然会导致进程失败
-
例如:磁带设备,录音机
-
可能发生死锁
-
2.死锁(Deadlock)
2.1 必要条件
导致死锁有四个必要条件:
-
互斥(Mutual Exclusion Condition):每个资源只有两种状态:分配给一个资源,或者待分配(Available)
-
拥有并等待(Hold and Wait Condition):进程持有了一些资源,并请求了额外的其他资源
-
没有抢占(No Preemption Condition):保证被某个进程持有的资源不会被其他资源强制拿走
-
循环等待(Circular Wait Condition):存在一系列进程,例如P1 is waiting for P2, P2 is waiting for P3, P3 is waiting for P1
2.2 死锁模型
关于资源分配图的基本信息:
-
如果图中没有循环,则没有死锁
-
如果图中包含一个循环
-
如果每个资源类型只有一个实例,则发生死锁
-
如果每个资源类型有多个实例,则可能出现死锁
-
处理死锁的方法:
-
忽略死锁的发生
-
允许允许系统进入死锁状态,然后恢复,依靠死锁检测和恢复
-
确保系统永远不会进入死锁状态
-
动态避免
-
预防
-
3.鸵鸟算法(Ostrich Algorithm)
就是重启系统
4.死锁探测(Deadlock Detection) & 死锁恢复(Deadlock Recovery)
4.1 概述
-
允许系统进入死锁状态
-
定期运行死锁检测算法
-
检测到死锁后,运行恢复算法
-
尽管有一些缺点,数据库系统还是这样做了
4.2 死锁检测(Deadlock Detection)
4.2.1 概述
How:
-
每次发出资源请求时检查
-
CPU时间方面可能很高开销
-
-
每k分钟检查一次,或者只在CPU利用率低于某个阈值(threshold)时检查一次
4.2.2 每种类型
的单个资源
如果每个资源只有一个实例,则可以通过构造资源分配/请求图并周期检测死锁
Deadlock Detection算法:
-
对于图中的每个节点N,以N为起始节点,执行以下五个步骤:
-
将L初始化为空列表,并将所有弧标记为unmarked(L是所有节点的列表)
-
将当前节点添加到L的末尾并查看当前节点是否再L中出现两次。如果是,则图中包含一个循环
-
从给定的节点,查看是否有任何unmarked的请求弧,如果有,则进入步骤5,如果没有,则进入步骤6
-
随机选择一个unmarked的请求弧并标记为marked,然后跟随它到新的节点,然后进入步骤3
-
如果该节点是初始节点,则途中不包含任何循环,算法终止。否则,我们就进入了死胡同,删除它并返回到前一个节点,使其成为当前节点,然后转到步骤3
示例:
对于每种资源只有一个实例的,直接画出分配/请求图,然后找环即可
4.2.3 每种类型的多个资源
N个进程,P1 到 Pn
资源类的数量:m
-
Ei: resources of class i(1 <= i <= m)
E: 现有的资源向量
A: 可用的资源向量
C: 当前分配资源矩阵
R: 请求资源矩阵
死锁检测算法(感觉有点银行家算法那味):
向量比较:(A <= B if and only if Ai <= Bi for 0 <= i <= m)
每个进程最初都为unmarked
-
寻找一个unmarked的进程Pi,Ri小于或等于A,则Pi的请求可以满足
-
如果找到这样的进程,将C的第i行添加到A,mark该进程并返回步骤1
-
如果不存在这样的进程,则算法终止,如果存在unmarked进程,则发生dead lock
4.3 从死锁中恢复
通过抢占(preemption)恢复:
-
从其他进程获取资源
-
取决于资源的性质
回滚恢复:
-
周期检查点进程
-
将进程的状态(内存映像和资源状态)写入文件
-
-
使用这个保存状态
-
如果发现进程陷入僵局,则重新启动该进程
通过kill进程进行恢复:
-
这是打破僵局最简单的方法
-
如何选择kill哪个进程
-
kill在死锁中的一个进程,然后其他进程获得其资源
-
kill不是在死锁中的进程, 从而使死锁中的进程获取其资源
-
kill可以重头运行而不会产生不良影响的进程
-
5.死锁避免(Deadlock Avoidance)
5.1 概述
当一个进程请求一个可用的资源时,系统必须决定立即分配资源是否会使系统处于安全状态。
这种技术要求系统在可能发生死锁的情况下不分配资源,
这种方法非常保守,因为仅仅因为可能发生死锁并不意味着死锁一定会发生
这种方法要求系统具有一些额外的先验信息可用
最简单且最有用的模型要求每个进程声明可能需要的每种类型资源的最大数量
5.2 安全/不安全状态
当前状态:哪些进程拥有哪些资源
安全状态:
-
系统无死锁
-
存在一个调度顺序,导致每一个进程运行到完成,即使它们都立即请求最大资源
当一个进程请求一个可用资源时,系统必须决定立即分配是否使系统处于安全状态
不安全状态:
-
处于不安全状态并不是意味着系统一定会发生死锁
5.3 银行家算法
银行家算法的基本思想和原理:
-
资源分配:每个进程在开始时必须声明其最大资源需求量(Request矩阵),当前已分配资源量(Current矩阵)和剩余的资源量(Available矩阵)。银行家算法将这些信息组织称矩阵形式,称为资源分配矩阵
-
安全性检查:银行家算法通过安全性检查来确定是否允许分配资源给某个进程。如果系统当前状态下存在一种资源分配序列,使得所有进程都你能顺利执行并完成,则系统是安全的。
-
资源分配规则:
-
当进程请求资源时,系统回显判断分配给该进程资源后是否仍然是安全状态,如果安全则分配资源,否则,推迟分配,直到系统重新处于安全状态。
-
当进程释放资源是,系统会重新计算安全状态,并可能重新分配资源给其他进程。
-
6.死锁预防(Deadlock Prevention)
打破以下的情况:
-
Mutual Exclusion
-
Hold an Wait
-
No Preemption
-
Circular Wait
5.1 Mutual Exclusion Condition
概述:
-
所有的系统资源必须能够以共享模式使用
-
有些设备(比如printer)可以被假脱机(spool)处理
-
示例:通过假脱机打印机输出,并将实际的打印机分配给打印机守护进程(printer daemon)
-
打印机守护进程不请求其他资源,因此打印机不可能出现死锁
-
假脱机空间是有限的,因此这个决策仍然可能出现死锁
-
两个进程各自占用了一半的可用空间,无法继续,因此磁盘上出现了死锁
-
-
原则:
-
避免在非绝对必要时分配资源
-
尽可能少的进程实际占用资源
问题:不是所有的设备都可以假脱机处理
5.2 Hold and wait condition
为了确保系统中永远不会出现hold and wait的情况,我们必须保证,每当一个进程请求一个资源时,它不会占用任何其他资源
Approach 1:
-
要求所有进程在开始执行之前请求它们的所有资源
-
如果一切都可以用,则将为进程分配它所需要的任何东西,并可以运行到完成
-
如果一个或多个资源繁忙,则进程将等待
-
在大型机领域有时也会这样做
-
-
问题:
-
可能在运行开始时不知道所需的资源
-
当然,如果我们能做到这一点,可以使用银行家算法
-
-
资源不会得到有效利用
-
从磁带中读取数据,然后分析,然后写回磁带
-
在整个过程中,磁带将无法被其他进程使用
-
-
Approach 2:
-
进程必须放弃所有资源,然后请求所有立即需要的资源
-
可能适用于某些程序,但许多程序不可能这样做
-
-
问题:如果必须保留某些资源,则不起作用
Approach 3:
-
在进程获得任何资源后设置计时器
-
计时器到期后,进程必须强制释放该资源
5.3 No Preemption Condition
概述:
-
一个进程只有在以下情况下才被允许强制抢占其他进程所有拥有的资源
-
它是高优先级进程或系统进程
-
victim进程正在等待状态
-
-
难以实现的做法:
-
无法在打印过程中将打印机从进程中取出
-
不能从进程中任意取走信号量
-
可能正在更新一个共享区域
-
-
不能拿走打开的流、管道和插座
-
需要非常小心地编写进程,可能会使用信号
-
-
Approaches :
-
资源虚拟化
-
部分资源不支持
-
如果一个进程持有一些资源,并请求另一个不能立即分配的资源
-
被抢占的资源被添加到进程正在等待的资源列表中。只有当进程能够重新获得它的旧资源以及它正在请求的新资源时,进程才会重新启动
-
5.4 The Circular Wait Condition
Approach 1:一次请求一个资源,当请求下一个资源时,释放当前资源
Approach 2:资源的全局排序
-
请求必须按递增的顺序提出
-
Req(resource 1), req(Resource 2)
Approach 3:方法2的变体
-
任何进程请求的资源都不能低于它所拥有的资源
7.其他
7.1 二相锁
二相锁法是一种用于管理和并发访问共享资源的技术,常用于OS中的数据库管理系统。它的主要目的是确保并发操作的一致性和避免数据访问产生的冲突,从而防止数据不一致的和其他相关问题:
基本原理:
-
两个阶段:
-
生长阶段:在这个阶段,事务可以获取锁,但不能释放任何锁。如果一个事务请求锁并获得了它,那么它可以继续请求并获得其他所需的锁。一旦事务释放了任何一个锁,它就不能再获取任何其他的锁
-
缩减阶段:在这个阶段,事务可以释放锁,但不能获取新的锁,一旦事务释放了所有的锁,它就进入了完成状态
-
-
锁类型:
-
共享锁:多个事务可以同时持有共享锁,表示它们只读共享资源。共享锁不阻止其他事务也获取共享锁。
-
排他锁:一次只能由一个事务持有,表示它正在写入资源。排他锁会阻止其他事务获取共享锁或排他锁
-
-
保持和等待规则:
-
保持规则:一个事务在获取锁后可以持有它,直到事务结束
-
等待规则:如果一个事务无法立即获取所需的锁,它可以等待其他事务释放锁,但不会导致死锁。
-
7.2 通信死锁
资源死锁:
-
进程需要为一个活动提供多个资源
-
如果一个集合中的一个进程请求的资源是同一个集合中的另一个进程持有的资源,则会发生死锁,并且它必须接收所有请求的资源才能继续前进
通信死锁:
-
进程在一组中等待与其他进程通信
-
集合中的进程在等待另一个进程的消息,并且在接收到等待的消息之前,集合中的任何进程都不会发起消息
7.3 活锁
进程运行,但没有任何进展
死锁和活锁都会导致饥饿
但饥饿可能有其他原因导致:
-
MLQ调度,其中一个队列国控
-
内存请求:无限制的100MB请求流可能会使一个200MB的请求饥饿
7.4 饥饿(Starvation)
概述:
-
饥饿时进程无法定期获得完成任务所需的共享资源的结果,因此无法获得任何进展
-
死锁是一种状态,在这种状态下,一组动作的每个成员都在等待其他成员释放锁
-
另一方面,活锁几乎与死锁相似,除了活锁中涉及的进程的状态不断地相互变化,但是没有进展
7.5 进程管理
进程组件:
-
定义进程行为的程序
-
过程所处理的数据及其产生的结果
-
提供执行环境的一组资源
-
一种状态记录,用于跟踪执行过程的进度和控制
进程管理的功能:
-
实现CPU共享(就是调度)
-
按照某些策略将资源分配给流程
-
实现进程同步和进程间通信
-
实现死锁策略和保护机制