操作系统之死锁
文章目录
操作系统的几种资源
可重用性资源和消耗性资源
-
可重用性资源
- 定义:可供用户重复使用的资源
- 性质:
- 可重用性资源的单元只能同一时间只能分配给一个进程,不允许共享
- 进程使用可重用性资源,需要一定顺序使用1)请求资源2)使用资源3)释放资源
- 操作系统中每一类可重用性资源的单元数目是固定的,进程在使用资源的过程不可创建或删除重用性资源
- 操作系统中的大多数资源都属于可重用性资源
-
消耗性资源
- 定义:与可重用性资源相对,消耗性资源是在进程运行过程中,由进程动态的创建和消耗的资源,又称为临时性资源
- 性质:
- 在进程运行过程中,消耗性资源的单元数目是可以不断变化的
- 进程运行过程中,可以创造消耗性资源
- 进程运行过程中,进程可以消耗一定数目的消耗性资源,而不再将该资源返回给资源类
可抢占性资源和不可抢占性资源
- 可抢占性资源
- 定义:某进程在获得这类资源后,该资源可以随时被其他进程或系统抢占
- 不可抢占性资源
- 定义:与不可抢占性资源相对,某进程获得这类资源后,该资源不能被其他进程或系统抢占,只有等进程用完之后自行释放该资源。
死锁的起因
- 竞争不可抢占性资源引起死锁
- 竞争可消耗性资源引起死锁
- 进程推进顺序不当引起死锁
死锁的定义、必要条件及处理方法
死锁的定义
如果一组进程中的每一个进程都在等待仅有该组进程中的其他进程才能引发的事件,则称该组进程是死锁的。
产生死锁的四个必要条件
产生死锁的原因有多种,但都是具备了一定的条件才形成死锁,产生死锁必须满足四个条件:
- 互斥条件:进程对分配到的资源进行排他性使用,不共享
- 请求和保持条件:进程在请求被其他进程所占有的资源,成阻塞状态时,保持自己所占有的资源不放
- 不可抢占条件:进程的资源不可抢占,只能等执行完毕后自行释放
- 循环等待条件:进程组每一个进程都在等待另一个进程所占用的资源,形成一个循环链
处理死锁的方法
- 预防死锁:破坏必要条件
- 避免死锁:防止进程进入不安全状态
- 检测死锁:可通过检测出死锁,从而采取一定措施
- 解除死锁:若检测到死锁,便采取措施解除死锁,通常是撤销一些进程
四种方法从上到下对于死锁的防范程度不断减弱,但资源利用率不断提高
预防死锁
预防死锁通常是通过破坏死锁的四个必要条件中的后三个来避免产生死锁。
破坏“请求和保持”条件
可通过两个不同的协议来保证:当一个进程在请求资源时,该进程不能持有不可抢占资源。从而破坏“请求和保持”条件
- 第一种协议
- 内容:所有进程在运行之前,必须一次性申请其整个运行过程中需要的所有资源
- 优点:简单易行、安全
- 缺点:
- 资源被严重浪费
- 使进程经常出现饥饿现象
- 第二种协议
- 内容:允许进程在只获得运行初期所需要的资源时,便开始运行。在运行过程中逐步释放自己所占有的,且使用完毕的资源。然后再去请求下一运行阶段所需要的资源
- 优点:提高了资源的利用率,减少发生饥饿现象的几率
破坏“不可抢占”条件
通过一种协议来破坏“不可抢占条件”
- 协议:
- 协议内容:当一个已经保持了某些不可抢占资源的进程,提出新的资源请求而得不到满足时,该进程必须释放它保持的所有资源,待以后需要时再申请。可以理解为这些资源被抢占了
- 优点:破坏了不可抢占条件
- 缺点:
- 方法比较复杂,实现代价大
- 可能造成前一阶段工作的浪费,延长了进程的周转时间,降低系统的吞吐量。
破坏“循环等待”条件
对系统的各类资源类型进行线性排序,并赋予不同的序号。
- 协议:
- 内容:规定每个进行必须按序号递增的顺序请求资源。如果需要多个同类资源,必须一起请求。假如某进程申请到了序号较高的资源又想申请序号较低的资源时,必须先释放序号较高的资源,再去申请序号较低的资源
- 优点:
- 避免资源分配途中出现环路,从而破坏了“循环等待”条件
- 提高了资源利用率,系统的吞吐量
- 缺点:
- 各类资源的序号必须相对稳定,从而限制了新类型设备的增加
- 在实际中,可能会出现某些作业使用各类资源的顺序与系统规定的顺序不同,从而造成资源的浪费。
- 按固定次序去申请资源,限制了用户自主得进行编程。
避免死锁
与预防死锁相比,避免死锁也属于事前预防的措施,但并不是通过破坏形成死锁的必要条件来实现,而是通过在资源动态分配过程中,防止系统进入不安全状态,来避免死锁。
安全状态与不安全状态:
- 安全状态:安全状态,指系统能按某种进程推进顺序 ( P 1 , P 2 , . . . , P n ) (P_1,P_2,...,P_n) (P1,P2,...,Pn)为每个进程分配所需的资源,直至满足进程的所有需求,使每个进程都可顺利完成。该推进顺序称为安全序列
- 不安全状态:与安全状态相对,如果不存在进程推进顺序,使得每个进程都可顺利完成,则称系统处在不安全状态中。
- 需要注意的是:系统处于安全状态,则一定不会出现死锁。而如果系统处于不安全状态,可能会出现死锁,并不是一定会出现死锁。
避免死锁的方法即为,在系统进行资源分配之前,先计算此次资源分配的安全性,如果此次分配不会导致系统进入不安全状态,则执行分配,而如果此次分配会导致系统进入不安全状态,则不执行分配。
银行家算法(避免死锁算法)
银行家算法:当一个新进程进入系统时,该进程必须申明在运行过程中所需要的每种资源的最大数目,且该数目不能超过系统拥有的资源总量。当进程请求某组资源时,系统必须先确定系统中是否有足够的该类资源供以分配给该进程。若有,通过安全性算法来计算,将资源分配给该进程后,是否会使系统处于不安全状态,如果不会处于安全状态,则将资源分配给该进程,否则让进程等待。若没有,进程等待。
-
数据结构
实现银行家算法,必须有四种数据结构,用以描述系统中可使用的资源数目、所有进程对于各类资源的最大需求、系统中已分配资源的情况、各进程还需要多少资源的情况
- 可利用资源向量 A v a i l a b l e Available Available, A v a i l a b l e [ j ] = K Available[j]=K Available[j]=K 表示系统中现有可利用的 R j R_j Rj类资源 K K K个
- 最大需求矩阵 M a x Max Max, M a x [ i , j ] = K Max[i,j]=K Max[i,j]=K 表示进程 i i i需要 R j R_j Rj类资源的最大数目为 K K K个
- 分配矩阵 A l l o c a t i o n Allocation Allocation, A l l o c a t i o n [ i , j ] = K Allocation[i, j]=K Allocation[i,j]=K 表示进程 i i i已分得 R j R_j Rj类资源 K K K个
- 需求矩阵 N e e d Need Need, N e e d [ i , j ] = K Need[i,j]=K