预防死锁之银行家算法

如果转载请注明出处:http://blog.csdn.net/gophers

银行家算法是一种可以用来预防死锁的检测算法,正像这种算法的名字一样,系统在分配资源情况就和银行家管理银行资金的情况是相似的。银行家要在贷款的时候协调各个客户之间的业务,最好的情况就是就是把当前的资金合理的分配出去,让余下来的资金依然足够应付近期的其他业务,而且能够确保在有新客户要贷款时之前贷出去的资金已经被收回。操作系统在协调各个进程之间的资源占用关系时也可以套用这种方法。

银行家算法主要由两个部分构成,一个是Safety Algorithm(安全状态检测算法),另一个是Resource-Request Algorithm(资源请求算法)。这两个算法是协同工作的,它们相互合作以预防操作系统发生死锁的情况。资源请求算法不会单独使用的,通常每次调用完资源请求算法都会再去调用安全检测算法。

在讲解银行家算法之前,我们先来定义一些全局数据结构,这些数据结构的定义对理解银行家算法来说至关重要!请耐下性子看仔细,而且要看懂,在继续将下去的时候脑子里也应该随时反应到这些数据结构有什么用:

先假设系统中的进程有P个,资源有R种,我们要定义如下数组(或二位数组)

1.
Available

Available是一个数组,它的长度等于R,也就是和资源的数量相同。数组里每一个元素的值代表了当前系统中该种资源可以获取的数目。简而言之,Available就是当前系统中各种资源的可用个数。一定要注意是当前哦~

2.
Max

Max是一个二维数组,定义为Max[P][R],代表P个进程每个进程要完成自己的任务所需的R种资源里每种资源的数量。比如Max[0][3]=5表示第0个进程要完成自己的任务总共需要第三种资源5个。

3.
Allocation

Allocation是一个二维数组,定义为Allocation[P][R],它表示每个进程已经被分配到的每种资源的个数。比如Allocation[0][3]=2表示第0个进程已经被系统分配了2个第三种资源。

4.
Need

Need也是一个二维数组,定义为Need[P][R],它表示每个进程要完成自己的任务(其实就是相应的Max值)还需要每种资源各多少个。比如通过上面的Max和Alloction我们可以知道Need[0][3]=3,因为第0个进程要完成自己的任务一共需要5个(Max)第三种资源,已经分配给了它2个(Allocation),还需要3个(Need)才可以玩成任务。也就是说,Need = Max -
Allocation 。

当然,如果你要实现一个具体的银行家算法程序的话就不必非要拘泥于是不是非要定义成数组这种问题了,具体的情况根据自己的实现来决定。

在搞懂了这4个数据结构之后我们就可以开始讲解银行家算法的两个算法了。

安全状态检测算法

安全状态检测算法的流程如下:

1.
先初始化两个数组,一个是Finish(长度为P),另一个是Available(长度为R),Finish表示某个进程是否已经执行完了它的任务,一开始把所有的元素都置为false,Available就是上面说过的那个啦,代表当前系统中每种资源的可用个数。

2.
不断扫描所有进程,当前扫描到了进程i,如果:

a. Finish[i] == false

b. Need[i] <= Available

这两个条件都成立的话就进行第3步,否则执行第4步。

3. Available += Allocation[i] 并置 Finish[i] = true,继续执行第2步。

4.
如果Finish中的元素都是true,即所有进程都已经执行完,则可以判定系统属于安全状态!

如果你仔细领悟的话就会发现安全状态检测算法原理是:

系统先把当前所有剩下的资源都像贷款一样分配给某个进程,但要确保这个进程拿了这笔“贷款”之后一定可以完成它的任务(也就是Allocation+Available >= Max),在这个进程执行完了它的任务后系统就把“贷款”和之前分配给它的所有资源都回收回来,就好像银行家把贷款连同利息一起回收回来一样,这时系统的“本金”就成了“贷款+利息”,也就是当前的Available等于之前的Available加上已执行完的进程的Allocation.

这时系统可以用这笔更多的“本金”继续贷款给某个其他进程,同样,在这个进程执行完毕后系统会连同之前分配给它的资源一起回收回来,这样不断往复,系统就通过这样从给低需求的进程贷出所有可用资源并不断回收资源从而积累可用资源来解决更多需求更大的进程。如果系统的“本金”不足以带给任何一个进程,则表示系统目前处于不安全的状态,随时可能发生死锁。

资源请求算法

如果某个进程i发起了资源分配申请:

1.
如果 Request[i] > Need[i] 则拒绝申请

2.
如果 Request[i] > Available[i] 则拒绝申请

3.
如果1、2步都通过了就进行如下计算:

Available -= Request[i]

Allocation[i] += Request[i]

Need[i] -= Request[i]

这个计算并不是真正改变了原先的Available、Allocation和Need,这些计算的值都是临时的

4.
用安全状态检测算法检测计算完毕后的系统状态是否处于安全状态,如果处于安全状态则进程i的这次请求生效,否则只能推迟这次的申请

资源请求算法的原理就是在进程请求的资源不超过系统当前可用资源的前提下,先同意分配试一下,然后通过安全态检测算法来检验这样分配后的系统是否安全,如果是安全的就真的同意这样分配,如果不安全就推迟这次分配。

如果讲解到这里还有点笼统,那么就据一个例子来说明一下银行家算法的具体实例,这个例子在Abraham Silberschatz的《Operation System Concepts》上可以找到:

假设现在有5个进程P0—P1,有三种资源ABC,系统目前的资源调配情况如下面这张列表:

我们先通过安全状态检测算法看一看目前的系统状态是否是安全的:

因为Need[P1] < Available,所以 Available = 3 3 2 + 2 0 0 = 5 3 2, Finish[P1] = true

这时Available就成了5 3 2,继续往下找

发现Need[P3] < Available,所以 Available = 5 3 2 + 2 1 1 = 7 4 3,
Finish[P3] = true

在接下来

Need[P4] < Available, Available = 7 4 3 + 0 0 2 = 7 4 5,Finish[P4] = true

Need[P0] < Available, Available = 7 4 5 + 0 1 0 = 7 5 5,Finish[P0] = true

Need[P2] < Available, Available = 7 5 5 + 3 0 2 = 10 5 7,Finish[P2] = true

算到这里Finish中所有的元素都已经置为了true,也就是说所有的进程都已经执行完毕了,目前系统处于安全状态~

如果现在P1发出一个请求Request = 1 0 2

因为1 0 2既小于Need[P1]又小于Available,所以我们调用资源请求算法,计算之后的结果如下:

Available = 3 3 2 - 1 0 2 = 2 3 0

Allocation = 2 0 0 + 1 0 2 = 3 0 2

Need = 1 2 2 - 1 0 2 = 0 2 0

用红色标出的数据就是与前一状态不同的部分

然后我们在调用安全状态检测算法检查变化后的系统是否处于安全状态就可以了,步骤和一面完全一样,通过检验后会发现给P1分配1 0 2之后系统依然可以处于安全状态,所以同意此次分配。

时间: 2024-10-24 02:41:07

预防死锁之银行家算法的相关文章

《操作系统、预防进程死锁的银行家算法》

预防进程死锁的银行家算法 原文:https://blog.csdn.net/houchaoqun_xmu/article/details/55540792 一.概念介绍和案例解析 银行家算法中的数据结构 可利用资源向量Available:   这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变.如果Available[j]=K,则表示系统中现有Rj类资源K个. 最大需求矩阵Max:   

避免死锁的银行家算法C++程序实现

 本篇博文为追忆曾经写过的算法系列第二篇(20081021) 温故知新 目的:具有代表性的死锁避免算法是Dijskstra给出的银行家算法.本实验是基于银行家算法的思想通过编写C++程序实现银行家算法的计算机程序化,使其更实用.同时也加深了有关自愿申请.避免死锁等概念,体会避免死锁的实际实现过程与方法. 要求: 1.设定进程p对各类资源r合理的最大需求max及初值确定:2.设定系统提供资源初始状况allocation:3.设定每次某个进程对各类资源的申请表示need:4.编制C++程序,基于

避免死锁的银行家算法

多线程操作系统在进程调度(资源分配)的时候可能会发生死锁. 引起死锁的直接原因是竞争不可抢占的互斥资源.这种资源有可能是临界资源,例如打印机:也有可能是可消耗性资源,例如信号量. 引起死锁的间接原因进程推进顺序不当.即系统单独运行进程P1或者P2都没有问题,但是调度两个进程同时进行时,由于调度顺序导致两个进程竞争资源产生死锁. ----------------------------- 产生死锁的四个必要条件: 1.互斥条件.进程已经分配到的资源具有互斥性,不能同时被其他进程共享. 2.请求和保

多任务死锁和银行家算法

1 import threading 2 import time 3 4 5 class MyThead1(threading.Thread): 6 def run(self): 7 # 对mutexA上锁 8 mutexA.acquire() 9 10 # mutexA上锁后,延时1秒,等待另外的那个线程,把mutexB上锁 11 print(self.name+"-----do1----up-----") 12 time.sleep(1) 13 14 # 对mutexB上锁,但是此

银行家算法 C++实现

操作系统中预防死锁的银行家算法,测试用例来自<计算机操作系统(第四版)>113页例题. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #define Process_Max 100 //进程数量最大值 #define Resource_Max 100 //资源种类最大值 using namespace std; int Available[Resou

死锁的避免——银行家算法

银行家把一定数量的资金供多个用户周转使用.当顾客对资金的最大申请量不超过银行家现金时,就可接纳一个新顾客:顾客可以分期借款:但借款总数不能超过最大申请量:银行家对顾客的借款可以推迟支付,但一定是顾客总能在有限的时间里得到借款:当顾客得到全部资金后,他一定能在有限时间里面归还所有资金. 采用银行家算法分配资源时候,测试进程对资源的最大需求量,如果系统现存的资源可以满足他的最大需求量时,就满足进程当前的申请,否则就推迟分配.这样做,能保证至少有一个进程可得到需要的全部资源而执行到结束,然后归还资源供

死锁产生的原因和必要条件及预防死锁的方法及死锁的检测与解除

产生死锁的原因和必要条件: 产生死锁的原因: 1.竞争资源.当系统中供多个进程共享的资源如打印机,公用队列等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁. 2.进程推进顺序非法.进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁. 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁.其次,进程运行推进顺序与速度不同,也可能产生死锁. 产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个

银行家算法

我们可以把操作系统作为一个银行家.操作系统管理的资金相当于银行家的资源.过程向操作系统请求分配相当于用户资源,银行贷款. 为了保证资金的安全性,银行规定: (1) 当资金客户最大需求不超过可用资金的银行家可以接受客户; (2) 贷款,但贷款的总数不能超过最大需求量; (3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款; (4) 当顾客得到所需的所有资金后,一定能在有限的时间里归还所有的资金. 银行家算法数据结构 1)可利用资源向量A

[OS] 死锁相关知识点以及银行家算法详解

因此我们先来介绍一下死锁: 死锁特征 当出现死锁时,进程永远不能完成,并且系统资源被阻碍使用,阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,先深入讨论一下死锁的特征. ·必要条件 (1)互斥:至少有一个资源必须处于非共享模式,即一次只有一个进程使用.如果另一进程申请该资源,那么申请进程必须等到该资源被释放为止. (2)占有并等待:一个进程必须占有至少一个资源,并等待另一资源,而该资源为其他进程所占有. (3)非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放. (4)循环等待