OS不做人系列四之华尔街银行家

目录

前言:

 一、资源问题

二、死锁发生必要条件

三、预防死锁

四、死锁避免

五、死锁的检测与解除(可以当做概念简单了解一下,重点是银行家算法哦)

后记:


前言:

      大家好啊,欢迎来到了不做人系列的第四期,前面我们介绍同步互斥,各种进程骚操作,各种抢占资源,所以我们发现会出现死锁,大家都阻塞了,这样会浪费大量的系统资源,甚至导致系统的崩溃。所以我们需要拥有银行家的敏锐来处理死锁。那么我们一起来学习吧。

          先给出死锁概念吧,后面你会更加深刻的理解它:指两个或多个并发进程各自占有某种资源而又等待别的进程释放它们的资源的状态。

 

 一、资源问题

     在系统中有许多不同种类的资源,其中可以引起死锁的主要是,需要采用互斥访问方法的、不可以被抢占的资源,即临界资源。哈哈,突然想到了钱是万恶之源。我们接下来就来介绍一下资源分类吧:

扫描二维码关注公众号,回复: 11552471 查看本文章

1.可重用性资源和消耗性资源

1)可重用性资源

     可重用性资源是一种可供用户重复使用多次的资源,有如下性质:

(1)每一个可重用性资源只可以分给一个进程使用,不允许多个进程共享。

(2)进程在使用可重用性功能时,必须按照这样的顺序:

  • 请求资源,如果请求资源失败,请求进程将会被阻塞或循环等待
  • 使用资源
  • 释放资源

(3)系统中每一类可重用性资源中的单元数目是相对固定的,进程在运行期间既不能创建也不能删除它。

2)可消耗性资源

     可消耗性资源又被称为临时性资源,它是进程运行期间,由进程动态的创建和消耗的,有如下性质:

  • 每一类可消耗性资源的单元数目在进程运行期间是可以不断变化的
  • 进程在运行过程中,可以不断的创造可消耗性资源
  • 进程在运行过程中,可以请求若干个资源的消耗

2.可抢占性资源和不可抢占性资源

1)可抢占性资源

     例如:优先级高的进程可以抢占优先级低的进程的处理机。

2)不可抢占资源

     例如:进程读取一个不可分割完整数据的时候,不可以中断。

-------->  所以竞争不可抢占性资源会引起死锁

--------> 竞争可消耗性资源会引起死锁

--------> 进程推进顺序不当引起死锁


二、死锁发生必要条件

我们将进程分组的话,这里再给出死锁定义:

     如果一组进程中的每一个进程都在等待仅由该组进程中的其它进程才能引发的事件,那么该组进程时死锁的(Deadlock)。

      所以我们可以归纳一下死锁发生的必要条件(必要条件在这里的意思是:如果没有这四个条件,那么一定不会发生死锁(这里只要任意一个不成立,死锁就不会发生,如果发生有这四个条件,未必会发生死锁,这是离散数学的知识哦,高中也有)。

(1)互斥条件

(2)请求和保持条件

(3)不可抢占条件

(4)循环等待条件

这里举一个食堂吃饭的例子:

      加入食堂筷子在东边,碗筷在西边。张三和王四来了,只有一双筷子和一个碗,张三往东边跑,王四往西边跑,两人各自拿了一双筷子和一个碗。没办法,死锁了。

      如果他们是朋友可以接受公用,那么互斥条件就不成立了,死锁不会发生。

     如果张三或者王四愿意先给对方,那么保持条件就不成立了,死锁不会发生。

     如果张三抢了王四的,不可抢占条件不成立了,死锁不会发生。

     如果张三王四一看只有一双碗筷了,不等待出去吃了,那么循环等待条件不成立了,死锁不会发生。


三、预防死锁

1.破坏请求和保持条件

 1)第一种协议

     所以进程在开始运行之前必须一次性的申请其在整个运行过程中所需要的全部资源。这不就破坏了请求条件吗?但是缺点就是资源浪费严重,会发生饥饿现象。

2)第二种协议

     允许一个进程只获得运行初期所需的资源后,便开始运行。进程运行过程中再逐步释放已分配给自己的、且已用毕的全部资源,然后再请求新的资源。

2.破坏不可抢占条件

     可以规定当一个已拥有一定不可抢占资源的进程,请求新资源而得不到时,就释放自己的资源。

3.破坏循环等待条件

    我们可以对所有的资源进行线性排序,并赋予不同的序列号。就像上面举的食堂的例子,只要都编号就好了。


四、死锁避免

     上面的预防很有用,但是很多时候出于无奈我们都要满足这四个条件,所以我们要有银行家的思维,去看到后面的很多步,如果会死锁,那我就不走了。就像下象棋,高手总是能看到后面的第n步,反正我就顶破天那么2,3步,hahhaha

     好的,那么就来到了我们标题中提到的银行家算法:

     这个是迪杰斯特拉大牛提出来的,当时是为了银行工作的算法,就是避免发生交易失败导致损失。

     为实现银行家算法,每一个新进程在进入系统时,它必须申明在运行过程中,可能需要美中资源类型的最大单位数目,其数目不应超过系统拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程。若有,再进一步计算在将这些资源分配给进程后,是否会使系统处于不安全状态。如果不会,才将资源分配给它,否则让进程等待。

那好,这里提及一下安全状态:

     安全状态:

如果存在一个由系统中所有进程构成的安全序列p1,p2...pn,则系统处于安全状态。

     安全序列:

存在一个进程序列,如果对于每个进程Pi(1<=i<=n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程当前占有资源量之和,那么这个序列是安全序列。

     我们从银行家算法描述那里可以看到,我们需要四个数据结构:

(1)可利用资源向量Available

(2)最大需求矩阵Max

(3)分配矩阵Allocation

(4)需求矩阵Need

有如下关系:Need[i,j]=Max[i,j]-Allocation[i,j]

所以具体银行家算法如下:

     在说之前可以小题一下,其实思想就是通过资源的判断来未雨绸缪,哈哈哈

     设Requesti是进程Pi的请求向量,如果Requesti[j] =K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下属步骤进行检查:

(1)如果Requesti[j]<=Need[i,j],便转向步骤(2);否则认为出错,所需要的资源数已经超过最大值。这个都可以理解,请求的当然不能大于总的需要的呀。

(2)如果Requesti[j]<=Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。在第一步基础上再次判断是否足够。

(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:

  • Available[j] = Available[j] - Requesti[j];
  • Allocation[i,j] = Allocation[i,j] + Requesti[j];
  • Need[i,j] = Need[i,j] - Requesti[j];

其实就是将资源矩阵改变啦

(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,正式将资源分配给进程Pi,已完成本次分配;否则,将本次的试探分配作废,恢复原来的状态,无非就是加减法再次回去。

安全性算法如下:

(1)设置两个向量:

工作向量Work,它表示系统可提供给进程继续运行所需的各种资源数目,它含有m个元素,在指向安全算法开始时,Work = Available;

Finish:它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i] = false,有资源则改为true。

(2)从进程集合中找到一个能满足下述条件的进程:

首先Finish[i] = false; 然后Need[i,j]<=Work[j];若找到,执行步骤(3);否则,执行步骤(4)

(3)当进程Pi获得资源后,可顺利执行,直至完成,并释放分配给它的资源,执行:

Work[j] = Work[j] +Allocation[i,j];

Finish[i] = true;

go to step 2;

(4)如果所有进程的Finish[i] = true都满足,则表示系统处于安全状态,否则,处于不安全状态。


五、死锁的检测与解除(可以当做概念简单了解一下,重点是银行家算法哦)

那如果在系统中既不采取死锁预防措施,也没有死锁避免算法,,就很可能发生死锁。在这种情况下,系统会提供两个算法:

  • 死锁检测算法:用于检测系统状态,已确定系统中是否发生了死锁。
  • 死锁解除算法:如果发生了死锁,那么将系统从死锁状态中解脱出来。

这里大致说一下死锁解除,比如:抢占资源来解除,终止进程等方法,关于检测与解除更多的可以去找度娘理解哦。

后记:

     好的,华尔街银行家告诉我们要学会利用数据来避免某类事情的发生,也许这就是他们这么有钱的原因吧。银行家的代码会在Linux专栏中提到哦,如有误,请指出,谢谢。

猜你喜欢

转载自blog.csdn.net/qq_43919400/article/details/105848698