银行家算法 递归求所有安全序列
银行家算法-求所有安全序列

银⾏家算法-求所有安全序列银⾏家算法-求所有安全序列使⽤DFS(深度优先搜索)遍历求出所有的安全序列。
数据结构先上头⽂件说明,实现此算法⽤到的数据结构和命名。
#ifndef _DATA_STRUCTURE#define _DATA_STRUCTURE// 表⽰资源个数#define M (4)// 表⽰进程个数#define N (4)// 当前状态还剩多少可⽤的资源struct AvailableD;// 每个进程对每个资源的最⼤需求量struct MaxD;// 当前分配个每个进程的资源数⽬struct AllocationD;// 每个进程还需要多少资源数⽬(最⼤需求 - 当前分配)struct NeedD;// 当前状态每个进程请求的资源数量struct RequestD;// 存放安全序列的数据结构(名字叫 Queue 实际上是栈的实现【FILO先进后出】)struct QueueD;// 表明每个进程是否在安全序列中struct StatusD;typedef struct AvailableD *Available;typedef struct MaxD *Max;typedef struct AllocationD *Allocation;typedef struct NeedD *Need;typedef struct RequestD *Request;typedef struct QueueD *Queue;typedef struct StatusD *Status;Available create_available();Allocation create_allocation();Max create_max();Need create_need();Queue create_queue();int queue_full(Queue queue);int queue_empty(Queue queue);void queue_add(Queue queue, int data);int queue_get(Queue queue);void queue_display(Queue queue);Status create_status();void display_need(Need need);/* 更新 need 数组 */void update_need(Need need, Allocation allocation, Max max);/* 将 allocation 矩阵的第 row ⾏的值加(减)到 available ⾥ */void update_available(Allocation allocation, int row, Available available, int is_add);/* 检查 available 是否满⾜ need 的第 row ⾏的需求 */void check_available(Allocation allocation, Need need, Available available, int row, Queue queue, Status status);#endif算法步骤⾸先检查当前剩余的资源数⽬是否满⾜某个进程的需求量,也就是说判断 Available 向量中每⼀个资源数⽬是否⼤于等于 Need 矩阵中某⼀个进程的需求量;如果对于进程 row ,对每个资源数⽬的需求量⼩于当前可⽤的系统资源;⾸先检查当前进程是否已经在安全序列中,若存在就判断下⼀个进程;若当前进程 row 还没有处在安全序列,就开始深度优先搜索:将当前进程 row 已经分配到的系统资源数⽬加到当前可⽤的资源数⽬中,即 Allocation 矩阵中第row ⾏的所有数⽬加到 Available 向量中;然后将当前进程 row 添加到安全序列中(此安全序列是⼀个栈);递归调⽤搜索的函数,向下⼀个进程开始搜索;在搜索的过程中需要判断所有的进程是否已经添加到安全序列中,即查看安全序列(栈)的⼤⼩是否等于当前系统的进程数⽬;若达到了就将安全序列输出并且开始回溯;此判断应该放在深度优先搜索函数的前⾯,⽤来作为递归出⼝;然后将最近加⼊到安全序列中的进程从安全队列中删除,即从栈中弹出⼀个元素,记为 row;然后修改此进程row未加在安全序列中的状态;将此进程row收回的资源数⽬归还,即从 Available 向量中减去 Allocation 矩阵中第 row ⾏的数⽬;然后向下⼀个进程搜索。
操作系统实验二:银行家算法

操作系统实验⼆:银⾏家算法实验⼆银⾏家算法⼀、实验⽬的1、了解什么是操作系统安全状态和不安全状态;2、了解如何避免系统死锁;3、理解银⾏家算法是⼀种最有代表性的避免死锁的算法,掌握其实现原理及实现过程。
⼆、实验内容根据银⾏家算法的基本思想,编写和调试⼀个实现动态资源分配的模拟程序,并能够有效避免死锁的发⽣。
三、实验原理进程申请资源时,系统通过⼀定的算法判断本次申请是否不可能产⽣死锁(处于安全状态)。
若可能产⽣死锁(处于不安全状态),则暂不进⾏本次资源分配,以避免死锁。
算法有著名的银⾏家算法。
1、什么是系统的安全状态和不安全状态?所谓安全状态,是指如果系统中存在某种进程序列<P1,P2,…,Pn>,系统按该序列为每个进程分配其所需要的资源,直⾄最⼤需求,则最终能使每个进程都可顺利完成,称该进程序列<P1,P2,…,Pn,>为安全序列。
如果不存在这样的安全序列,则称系统处于不安全状态。
2、银⾏家算法把操作系统看作是银⾏家,操作系统管理的资源相当于银⾏家管理的资⾦,进程向操作系统请求分配资源相当于⽤户向银⾏家贷款。
为保证资⾦的安全,银⾏家规定:(1) 当⼀个顾客对资⾦的最⼤需求量不超过银⾏家现有的资⾦时就可接纳该顾客;(2) 顾客可以分期贷款,但贷款的总数不能超过最⼤需求量;(3) 当银⾏家现有的资⾦不能满⾜顾客尚需的贷款数额时,对顾客的贷款可推迟⽀付,但总能使顾客在有限的时间⾥得到贷款;(4) 当顾客得到所需的全部资⾦后,⼀定能在有限的时间⾥归还所有的资⾦。
操作系统按照银⾏家制定的规则设计的银⾏家算法为:(1)进程⾸次申请资源的分配:如果系统现存资源可以满⾜该进程的最⼤需求量,则按当前的申请量分配资源,否则推迟分配。
(2)进程在执⾏中继续申请资源的分配:若该进程已占⽤的资源与本次申请的资源之和不超过对资源的最⼤需求量,且现存资源能满⾜该进程尚需的最⼤资源量,则按当前申请量分配资源,否则推迟分配。
(3)⾄少⼀个进程能完成:在任何时刻保证⾄少有⼀个进程能得到所需的全部资源⽽执⾏到结束。
简述银行家算法

简述银行家算法银行家算法,也称为银行家安全算法,是一种用于避免系统资源的死锁现象的算法。
在操作系统中,当多个进程需要同时访问同一组资源并且它们的访问不可分割时,就会产生死锁现象。
在这种情况下,所有的进程都会被阻塞,无法进行任何工作。
银行家算法通过对系统资源的分配和管理,可以避免死锁现象的发生。
它主要包括以下几个步骤:1. 初始化系统:在系统启动时,需要确定每种类型的资源的数量和可用数量,并记录每个进程需要的最大资源数和已经分配的资源数。
2. 进行资源请求:当一个进程需要资源时,会向系统发送一个资源请求。
该请求指定了进程需要的资源类型和数量。
如果系统中有足够的资源可以分配给该进程,那么分配成功并将资源分配给该进程。
3. 检查资源分配是否安全:在分配资源之前,需要检查分配后系统是否处于安全状态。
安全状态是指在分配后,所有进程都能够完成它们的工作并释放所有资源。
如果系统处于安全状态,则分配资源并通知进程可以执行它们的任务。
4. 回收资源:当进程完成任务后,会释放它所占用的所有资源并通知系统。
系统会将这些资源重新分配给其他进程。
在银行家算法中,对于每个进程,都会维护一个资源请求向量和一个安全向量。
资源请求向量包含了进程当前所需要的资源数量,安全向量包含了系统中未分配的资源数量。
当系统收到一个资源请求时,会将该请求向量加入到系统资源向量中,并检查是否存在一个安全序列,该安全序列满足所有进程都可以完成它们的任务并释放它们所占用的所有资源。
如果存在这样的安全序列,则分配资源并通知进程可以执行它们的任务;如果不存在,则拒绝资源请求并等待其他进程的资源释放。
通过使用银行家算法,可以避免系统中的死锁现象,保证所有进程都可以完成它们的任务。
这种算法被广泛应用于操作系统和其他复杂的软件系统中,是保障系统安全性的重要工具。
银行家算法计算安全序列

银行家算法计算安全序列
银行家算法是一种用于判断系统资源分配是否安全的算法,用于避免死锁的发生。
安全序列是指系统能够按照一定的顺序满足所有进程的资源需求,同时避免死锁的发生。
下面是银行家算法计算安全序列的基本步骤:
1. 初始化:设置一个长度为n的数组work,代表可用资源的
数量,初始值为系统中每个资源的可用数量。
设置一个长度为
n的数组finish,用于记录每个进程是否已经得到了全部所需
资源,初始值均为false。
2. 循环检测:循环遍历进程,检查当前进程是否满足以下条件: - finish[i]为false(即当前进程未得到所需资源)
- 当前进程所需的资源量小于等于work(即系统有足够的资
源供当前进程使用)
如果满足以上条件,则将当前进程加入安全序列,并更新work的值,即work = work + allocation[i]。
将finish[i]设为true,表示当前进程已经得到了所需资源。
继续循环直到所有进程都满足以上条件或者没有进程满足以
上条件为止。
3. 检查安全性:检查是否存在一个安全序列,即所有进程都已经得到了所需的资源。
如果存在安全序列,则系统是安全的;否则,系统是不安全的。
通过以上步骤,可以计算出一个安全序列,用于判断系统资源分配是否安全。
操作系统之银行家算法

操作系统之银⾏家算法
银⾏家算法
银⾏家算法是解决死锁问题的。
那么怎么解决呢? 死锁的⼀个原因就是互斥资源, 如上图,有A,B,C三个资源,数量分别是
10,5,7,MAX表⽰的是每个进程需要该资源,需要多少,Allocation表⽰现在分配了多少,Need表⽰他们还需要多少,⾃然Max-
Allocation就能算出need。
那么怎样算Available呢?某个资源⼀共有的减去分配了的,就是当前可⽤的。
work表⽰当前可⽤的资源的数⽬,刚开始肯定就是3 3 2,这个表⽰我们的系统中的资源还剩多少,然后判断可以分配给哪个进程,把这个进程的名字写在前⾯,然后need就是这个进程需要的资源数,Allocation是这个进程当前分配了多少,work+Allocation为把两个加起来,意思就是系统执⾏这个进程,完了以后会释放之前分配给他的,然后这个系统中当前有的资源数就是work+Allocation。
执⾏完,最后的work+Allocation应该跟刚
开始系统的资源数相同。
「怎样判断系统是否安全呢?」 如果每个进程都能执⾏,也就是finish都为true,那么这个系统就是安全的,反之就不安全。
P1发出请求向量,是在他原来需要的1 2 2⾥,先要请求1 0 2,所以先要判断请求的向量是不是⽐需要的多,如果多肯定是不对的。
第⼆步,请求的向量需要⽐当前可⽤的少,这两个条件都满⾜以后,我们就把Allocation的向量增加请求向量,把Need向量减少请求向量,然后继续进⾏计算。
银行家算法实验报告

2011-2012学年第一学期计算机操作系统实验报告专业:计算机科学与技术班级:学号:姓名:提交日期:实验三银行家算法模拟【开发语言及实现平台或实验环境】C++/C#Microsoft Visual Studio 6.0/ Microsoft V isual Studio .NET 2003【实验目的】(1)进一步理解利用银行家算法避免死锁的问题;(2)在了解和掌握银行家算法的基础上,编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再检测和笔算的一致性。
(3)理解和掌握安全序列、安全性算法【实验要求】(1)了解和理解死锁;(2)理解利用银行家算法避免死锁的原理;(3)会使用某种编程语言。
【实验原理】一、安全状态指系统能按照某种顺序如<P1,P2,…,Pn>(称为<P1,P2,…,Pn>序列为安全序列),为每个进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。
二、银行家算法假设在进程并发执行时进程i提出请求j类资源k个后,表示为Requesti[j]=k。
系统按下述步骤进行安全检查:(1)如果Request i≤Need i则继续以下检查,否则显示需求申请超出最大需求值的错误。
(2)如果Request i≤A vailable则继续以下检查,否则显示系统无足够资源,Pi阻塞等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:A vailable[j]∶=A vailable[j]-Request i[j];Allocation[i,j]∶=Allocation[i,j]+Request i[j];Need[i,j]∶=Need[i,j]-Requesti[j];(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
计算机操作系统银行家算法

计算机操作系统必考题(银行家算法) 银行家算法( banker's algorithm )由 Dijkstra于1965提出,关键是将死锁的问题演示为一个银行家贷款的模型,由于能用于银行系统的现金贷款而出名。
一个银行家向一群客户发放信用卡,每个客户有不同的信用额度。
每个客户可以提出信用额度内的任意额度的请求,直到额度用完后再一次性还款。
银行家承诺每个客户最终都能获得自己需要的额度。
所谓“最终”,是说银行家可以先挂起某个额度请求较大的客户的请求,优先满足小额度的请求,等小额度的请求还款后,再处理挂起的请求。
这样,资金能够永远流通。
所以银行家算法其核心是:保证银行家系统的资源数至少不小于一个客户的所需要的资源数。
银行家算法是一种最有代表性的避免死锁的算法。
在避免死锁方法中允许进程动态地申请资源,但银行家算法在系统在进行资源分配之前(并不是真的不分配,这样就没法做了,只不过是试探性分配,不满足的话再恢复),应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
为实现银行家算法,系统必须设置若干数据结构。
要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全序列是指存在一个进程序列{P1,…,Pn}是安全的,不会死锁(至少两个线程占有某资源A,但是都不满足,剩余的资源A分配给谁仍然无法满足),安全状态如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态,安全状态一定是没有死锁发生;不安全状态不存在一个安全序列,不安全状态不一定导致死锁。
本算法在理论上是出色的,能非常有效地避免死锁,但从某种意义上说,它缺乏实用价值,因为很少有进程能够在运行前就知道其所需资源的最大值,且进程数也不是固定的,往往在不断地变化(如新用户登录或退出),况且原来可用的资源也可能突然间变成不可用(如打印机、磁带机可能被损坏)。
二.算法原理银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。
银行家算法 实验报告

淮海工学院计算机工程学院实验报告书课程名:《操作系统原理》题目:银行家算法班级: D学号:姓名:一、实验目的银行家算法是操作系统中避免死锁的典型算法,本实验可以加深对银行家算法的步骤和相关数据结构用法的更好理解。
实验环境Turbo C 2.0/3.0或VC++6.0实验学时4学时,必做实验。
二、实验内容用C语言编写一个简单的银行家算法模拟程序,用银行家算法实现资源分配。
程序能模拟多个进程共享多种资源的情形。
进程可动态地申请资源,系统按各进程的申请动态地分配资源。
要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源数量以及为某进程分配资源后的有关资源数据的情况。
三、实验说明实验中进程的数量、资源的种类以及每种资源的总量Total[j]最好允许动态指定。
初始时每个进程运行过程中的最大资源需求量Max[i,j]和系统已分配给该进程的资源量Allocation[i,j]均为已知(这些数值可以在程序运行时动态输入),而算法中其他数据结构的值(包括Need[i,j]、Available[j])则需要由程序根据已知量的值计算产生。
四、实验步骤1、理解本实验中关于两种调度算法的说明。
2、根据调度算法的说明,画出相应的程序流程图。
3、按照程序流程图,用C语言编程并实现。
五、分析与思考1.要找出某一状态下所有可能的安全序列,程序该如何实现?要找出这个状态下的所有可能的安全序列,前提是要是使这个系统先处于安全状态,而系统的状态可通过以下来描述:进程剩余申请数=最大申请数-占有数;可分配资源数=总数-占有数之和;通过这个描述来算出系统是否安全,从而找出所有的安全序列。
2.银行家算法的局限性有哪些?银行家算法是一种最有代表性的避免死锁的算法。
银行家算法即把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
操作系统实验之银行家算法

操作系统实验之银行家算法操作系统实验——银行家算法一、实验目的1、理解银行家算法。
2、掌握进程安全性检查的方法与资源分配的方法。
二、实验内容与基本要求编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性。
现在系统中A、B、C、D 4类资源分别还剩1、5、2、0个,请按银行家算法回答:1、现在系统是否处于安全状态?2、如果现在进程P1提出需要0、4、2、0个资源的请求,系统能否满足它的请求?三、实验报告内容1、银行家算法和安全性检查算法原理银行家算法:银行家算法最初级原为银行系统设计,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。
在OS设计中,也可以用它来避免死锁。
为实现银行家算法,每个新进程在进入系统时它必须申明在运行过程中,可能需要的每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。
当某一进程请求时,系统会自动判断请求量是否小于进程最大所需,同时判断请求量是否小于当前系统资源剩余量。
若两项均满足,则系统试分配资源并执行安全性检查算法。
安全性检查算法 :安全性检查算法用于检查系统进行资源分配后是否安全,若安全系统才可以执行此次分配;若不安全,则系统不执行此次分配。
安全性检查算法原理为:在系统试分配资源后,算法从现有进程列表寻找出一个可执行的进程进行执行,执行完成后回收进程占用资源;进而寻找下一个可执行进程。
当进程需求量大于系统可分配量时,进程无法执行。
当所有进程均可执行,则产生一个安全执行序列,系统资源分配成功。
若进程无法全部执行,即无法找到一条安全序列,则说明系统在分配资源后会不安全,所以此次分配失败。
2、程序流程图3、程序及注释#include////////////////////////////////////////////////////////////////////////// //全局变量定义int Available[100]; //可利用资源数组int Max[50][100]; //最大需求矩阵int Allocation[50][100]; //分配矩阵int Need[50][100]; //需求矩阵int Request[50][100]; //M个进程还需要N类资源的资源量int Finish[50];int p[50];int m,n; //M个进程,N类资源///////////////////////////////////////////////////////////////////////// //安全性算法int Safe{int i,j,l=0;int Work[100]; //可利用资源数组for i=0;iWork[i]=Available[i];for i=0;iFinish[i]=0;for i=0;i{if Finish[i]==1continue;else{for j=0;j{if Need[i][j]>Work[j]break;}if j==n{Finish[i]=1;forint k=0;kWork[k]+=Allocation[i][k]; p[l++]=i;i=-1;}else continue;}if l==m{cout<<"系统是安全的"<<'\n'; cout<<"系统安全序列是:\n"; for i=0;i{cout<if i!=l-1cout<<"-->";}cout<<'\n';return 1;}}}////////////////////////////////////////////////////////////////////////////// /////银行家算法int main{int i,j,mi;cout<<"输入进程的数目:\n";cin>>m;cout<<"输入资源的种类:\n";cin>>n;cout<<"输入每个进程最多所需的各类资源数,按照"<for i=0;iforj=0;jcin>>Max[i][j];cout<<"输入每个进程已经分配的各类资源数,按照"<for i=0;i{forj=0;j{cin>>Allocation[i][j];Need[i][j]=Max[i][j]-Allocation[i][j];if Need[i][j]<0{cout<<"你输入的第"<j--;continue;}}}cout<<"请输入各个资源现有的数目:\n";for i=0;icin>>Available[i];Safe;while 1{cout<<"输入要申请的资源的进程号:第一个进程号为0,第二个进程号为1,依此类推\n";cin>>mi;cout<<"输入进程所请求的各个资源的数量\n";for i=0;icin>>Request[mi][i];for i=0;i{if Request[mi][i]>Need[mi][i]{cout<<"所请求资源数超过进程的需求量!\n";return 0;}if Request[mi][i]>Available[i]{cout<<"所请求资源数超过系统所有的资源数!\n"; return 0;}}for i=0;i{Available[i]-=Request[mi][i];Allocation[mi][i]+=Request[mi][i];Need[mi][i]-=Request[mi][i];}if Safecout<<"同意分配请求\n";else{cout<<"SORRY╮╯▽╰╭……你的请求被拒绝…\n"; for i=0;iAvailable[i]+=Request[mi][i];Allocation[mi][i]-=Request[mi][i];Need[mi][i]+=Request[mi][i];}}for i=0;iFinish[i]=0;char Flag; //标志位cout<<"是否再次请求分配?是请按Y/y,否请按N/n"; while 1{cin>>Flag;if Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n' break;else{cout<<"请按要求重新输入:\n";continue;}}if Flag=='Y'||Flag=='y'continue;else break;}4、运行结果以及结论图示为题目所给定的条件下的程序运行结果。
用递归方法求解全排列

用递归方法求解全排列全排列是指给定一组数,通过不同的排列顺序来得到所有的可能排列。
如果数的个数是n,则全排列的个数是n!(n的阶乘)。
递归方法是一个很好的解决全排列问题的方式。
下面就来介绍一下用递归方法求解全排列的过程。
1. 基本思路求解全排列的思路是从第一个数开始固定,然后对剩余的数进行全排列,这个过程是递归进行的。
递归终止的条件是当只有一个数时,直接输出这个数就是全排列的一个结果。
下面是一个比较标准的求解全排列的递归函数:```void permutation(char* pStr, char* pBegin){if (*pBegin == '\0')printf("%s\n", pStr);else{for (char* pCh = pBegin; *pCh != '\0'; ++pCh){swap(pBegin, pCh);permutation(pStr, pBegin + 1);swap(pBegin, pCh);}}}```2. 函数解析(1)函数参数说明函数有两个参数:char* pStr:表示要进行全排列的字符串,这个字符串会在递归过程中进行排列,最终生成全排列结果。
char* pBegin:表示当前正在固定的字符位置,也就是说,在递归处理中已经固定了前面的字符,pBegin指向下一个要固定的字符位置。
(2)递归终止条件如果pBegin指向了字符串的结尾,也就是说已经固定了整个字符串中的所有字符,那么就输出此时的全排列。
if (*pBegin == '\0')printf("%s\n", pStr);(3)递归循环体在循环体内部,通过一个for循环枚举下一次要固定的字符位置。
在固定字符之前,使用swap函数交换pBegin和pCh指针变量的内容,这一步的目的是交换要固定的字符和下一个将要固定的字符,以此来生成不同的全排列结果。
银行家算法

成绩:实验报告课程名称:操作系统实验项目:The Banker’s Algorithm姓名:专业:班级:学号:计算机科学与技术学院计算机系2019 年 6 月9 日哈尔滨理工大学计算机科学与技术学院计算机系实验报告实验项目名称:The Banker’s Algorithm一、实验目的1. 掌握银行家算法。
2. 输入进程个数、资源个数、进程对资源的最大需求,当前分配状态;输入进程个数、资源个数、进程对资源的最大需求,当前分配状态输入某个进程的资源请求,判断是否安全。
二、实验内容银行家算法是通过动态地检测系统中资源分配情况和进程对资源的需求情况来决定如何分配资源的,在能确保系统处于安全状态时才能把资源分配给申请者,从而避免系统发生死锁。
要记住的一些变量的名称1 Available(可利用资源总数)某类可利用的资源数目,其初值是系统中所配置的该类全部可用资源数目。
2 Max:某个进程对某类资源的最大需求数3 Allocation:某类资源已分配给某进程的资源数。
4 Need:某个进程还需要的各类资源数。
Need= Max-Allocation代码:#include<stdio.h>int m, n, z = 0;int Available[10];int Max[10][10];int Allocation[10][10];int p[10], Finish[10] = { 1 };int TestSafe(){int i, j, k = 0, l = z;int Work[10];for (i = 1; i <= m; i++)Work[i] = Available[i];for (i = 1; i <= n; i++)Finish[i]--;for (i = 1; i <= n; i++) {if (Finish[i] > 0)continue;for (j = 1; j <= m; j++) {if (Work[j] < Max[i][j] - Allocation[i][j])break;}if (j == m + 1) {Finish[i] = 1;for (k = 1; k <= m; k++)Work[k] += Allocation[i][k];p[l++] = i;i = 0;}if (l == n) {printf("系统是安全的\n");printf("系统安全序列是:\n");k = 1;for (i = 0; i < l; i++) {printf("P%d", p[i]);if (i != l - 1)printf("-->");}printf("\n");}}if (k == 0){printf("发生死锁,不存在安全序列。
银行家算法详解

银行家算法详解银行家算法( banker's algorithm )由 Dijkstra(1065)提出。
他将死锁的问题演示为一个银行家贷款的模型。
一个银行家向一群客户发放信用卡,每个客户有不同的信用额度。
每个客户可以提出信用额度内的任意额度的请求,直到额度用完后再一次性还款。
银行家承诺每个客户最终都能获得自己需要的额度。
所谓“最终”,是说银行家可以先挂起某个额度请求较大的客户的请求,优先满足小额度的请求,等小额度的请求还款后,再处理挂起的请求。
这样,资金能够永远流通。
银行家算法可以用以下图表表示:每个客户和银行家都有交易限额。
银行家只能和限额小于自己限额的客户进行交易。
一旦银行家的限额小于所有客户的限额,便发生了死锁。
如上图所示。
银行家分别和客户1,客户2,客户3进行了交易。
第一次交易时,所有客户的限额都小于银行家的限额,任何客户都可以实现借款;第二次交易时,客户3的限额大小银行家的限额,这时银行家会挂起客户3 的请求;第三次交易时,只有客户3可以进行交易,其它的交易都会被挂起。
直到客户3还款后,银行家才会考虑处理其它客户的交易。
银行家算法其核心是:保证自己的限额至少不小于一个客户的限额。
我们可以用填表法来快速解决银行家算法。
建立一个二维表格:每列数据表示每次交易各个参与者的限额。
这个表格第一列数据是银行家是客户的交易限额,每发生一次交易,增加一列,同时将银行家和发生交易的客户的限额减小。
直到银行家的限额小于某个客户的限额时,交易不能继续进行。
否则便发生死锁。
例题:1、操作系统分配资源时的一个重要考虑是避免死锁的发生.若系统中有同类资源 16 个,由四个进程 P1、P2、P3 和 P4 共享该资源。
已知P1、P2、P3、P4 所需的资源总数分别为8、5、9、6。
各进程请求资源的次序如下表,若系统采用银行家算法为它们分配资源,那么_(1)__依次申请分配会使系统进入不安全状态。
进程申请资源的情况。
实验二银行家算法

实验二银行家算法一、目的:加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用银行家算法,有效地防止和避免死锁的发生。
二、内容:银行家算法是避免死锁的一种重要方法,本实验要求编写和调试一个简单的银行家算法程序。
用银行家算法实现资源分配。
三、编程思想:首先分析银行家算法的数据结构,分析可利用资源向量Available、最大需求矩阵Max、分配矩阵Allocation、需求矩阵Need 、进程申请资源的关系,由所学知识可知;Need[i,j]=Max[I,j]-Allocation[i,j];当进程申请资源的时候;a)Requesti>Need[i]。
这种情况表示该进程的资源需求已超过系统所宣布的最大值,出错。
b)Requesti=Need[i]。
这种情况表示该进程现在对他所需的全部资源一次申请完成。
c)Requesti〉Need[i]。
这种情况表示该进程现在对它所需资源再进行部分的申请,剩余的资源以后再次申请。
当进程pi发出资源请求后;a)如果Requesti<=Need[i],转向步骤b,否则显示为出错,因为所需的资源数超过事先要求的最大值。
b)Requesti <=Available,便转向步骤三,否则则表示尚无足够资源,pi需等待。
c)假如系统将资源分配给pi则:Available=Available-RequestiAllocation[i]=Allocation[i]+RequestiNeed[i]=Need[i]-Request安全性算法检查(1)设置向量:工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,在执行安全性算法开始时,Work[]= Available[]。
Finish[],它表示系统是否有足够的资源分配给每个进程,使之运行完成。
开始时先做Finish[i]=0;当有足够的资源分配给进程时,再令Finish[i]=1。
银行家算法(安全序列)

银⾏家算法(安全序列)银⾏家算法银⾏家算法(Banker's Algorithm)是⼀个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的⼀种避免死锁产⽣的算法。
它以银⾏借贷系统的分配策略为基础,判断并保证系统的安全运⾏。
安全状态如果存在⼀个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。
安全状态⼀定是没有死锁发⽣。
不安全状态不存在⼀个安全序列。
不安全状态不⼀定导致死锁。
数据结构1)可利⽤资源向量Available是个含有m个元素的数组,其中的每⼀个元素代表⼀类可利⽤的资源数⽬。
如果Available[j]=K,则表⽰系统中现有Rj类资源K个。
2)最⼤需求矩阵Max这是⼀个n×m的矩阵,它定义了系统中n个进程中的每⼀个进程对m类资源的最⼤需求。
如果Max[i,j]=K,则表⽰进程i需要Rj类资源的最⼤数⽬为K。
3)分配矩阵Allocation这也是⼀个n×m的矩阵,它定义了系统中每⼀类资源当前已分配给每⼀进程的资源数。
如果Allocation[i,j]=K,则表⽰进程i当前已分得Rj类资源的数⽬为K。
4)需求矩阵Need。
这也是⼀个n×m的矩阵,⽤以表⽰每⼀个进程尚需的各类资源数。
如果Need[i,j]=K,则表⽰进程i还需要Rj类资源K个,⽅能完成其任务。
Need[i,j]=Max[i,j]-Allocation[i,j]算法原理我们可以把操作系统看作是银⾏家,操作系统管理的资源相当于银⾏家管理的资⾦,进程向操作系统请求分配资源相当于⽤户向银⾏家贷款。
为保证资⾦的安全,银⾏家规定:(1) 当⼀个顾客对资⾦的最⼤需求量不超过银⾏家现有的资⾦时就可接纳该顾客;(2) 顾客可以分期贷款,但贷款的总数不能超过最⼤需求量;(3) 当银⾏家现有的资⾦不能满⾜顾客尚需的贷款数额时,对顾客的贷款可推迟⽀付,但总能使顾客在有限的时间⾥得到贷款;(4) 当顾客得到所需的全部资⾦后,⼀定能在有限的时间⾥归还所有的资⾦.操作系统按照银⾏家制定的规则为进程分配资源,当进程⾸次申请资源时,要测试该进程对资源的最⼤需求量,如果系统现存的资源可以满⾜它的最⼤需求量则按当前的申请量分配资源,否则就推迟分配。
银行家算法

银行家算法银行家算法是一种用来避免操作系统死锁出现的有效算法,所以在引入银行家算法的解释之前,有必要简单介绍下死锁的概念。
死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
死锁的发生必须具备以下四个必要条件:1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。
如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不抢占条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)循环等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
避免死锁算法中最有代表性的算法就是Dijkstra E.W 于1968年提出的银行家算法,银行家算法是避免死锁的一种重要方法,防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。
为实现银行家算法,系统必须设置若干数据结构,同时要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全序列:是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。
安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。
安全状态一定是没有死锁发生。
银行家算法递归求所有安全序列

银行家算法递归求所有安全序列#include#include#include#include#define MaxResourceNum 101 //最大资源数100,(下标0未用)#define MaxProcessNum 101 //最大进程数100, (下标0未用)char * Safety[MaxProcessNum];//安全序列typedef struct Resource{ //资源结点char name[10]; //名称int num; //数量}Resource;Resource Available[MaxResourceNum]; //可利用资源向量Resource WorkRecord[MaxProcessNum][MaxResourceNum]; //查找安全序列时的Word记录int ResourceNum,ProcessNum; //资源数,进程数bool IsSafe=false; //当前或满足进程请求后状态是否安全typedef struct PCB{char name[10]; //进程名char status[10]; //状态int Max[MaxResourceNum]; //最大需求向量int Allocation[MaxResourceNum]; //分配向量int Need[MaxResourceNum]; //需求向量int Request[MaxResourceNum]; //请求向量bool Finish; //进程是否获得资源已完成struct PCB *next; //下一个结点}PCB;PCB *head=(PCB* )malloc(sizeof(PCB));//PCB链头指针PCB *tail=head; //尾指针//输入资源种类,数目void PrintAvailable(){printf("请输入资源种类数目:");scanf("%d",&ResourceNum);printf("请输入资源的名称:\n");getchar();for(int i=1;i<=ResourceNum;i++){gets(Available[i].name);}printf("请输入资源的数目:\n");for(i=1;i<=ResourceNum;i++)scanf("%d",&Available[i].num);}//输入进程的资源情况void InputPCB(){void ShowStatus() ;void CurrentCheck();printf("请输入进程数");scanf("%d",&ProcessNum);getchar();printf("输入%d个进程的资源分配情况:\n",ProcessNum); for(int i=1;i<=ProcessNum;i++){PCB *p=(PCB *)malloc(sizeof(PCB));printf("请输入进程名:");gets(p->name);printf("输入最大需求向量:");for(int i=1;i<=ResourceNum;i++)scanf("%d",&p->Max[i]);printf("输入分配向量:");for(i=1;i<=ResourceNum;i++)scanf("%d",&p->Allocation[i]);printf("推得需求向量为:");for( i=1;i<=ResourceNum;i++){p->Need[i]=p->Max[i]-p->Allocation[i];printf(" %d",p->Need[i]);}p->next=NULL;p->Finish=false;printf("\n");getchar();tail->next=p;tail=p;}PCB *p=head->next;for( i=1;i<=ProcessNum;i++){for(int j=1;j<=ResourceNum;j++) Available[j].num-=p->Allocation[j];p=p->next;}printf("\n");CurrentCheck();printf("\n");ShowStatus();}//检测当前状态是否安全void CurrentCheck(){void safety(PCB *head,Resource Work[],int n); Resource Work[MaxResourceNum];for(int i=1;i<=ResourceNum;i++){strcpy(Work[i].name,Available[i].name); Work[i].num=Available[i].num;}safety(head,Work,1);if(IsSafe){printf("故系统安全 \n");}else{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_RED);printf("当前时刻系统处于不安全状态,请重新设置\n");SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_GREEN);}}//显示当前资源分配状态void ShowStatus(){printf("当前系统状态:\n");printf(" Max Allocation Need Available \n");printf(" ");for(int k=1;k<=4;k++){for(int i=1;i<=ResourceNum;i++)printf(" %s ",Available[i].name);printf(" ");}printf("\n");PCB *p=head->next;for(int i=1;i<=ProcessNum;i++){printf("%s",p->name);printf(" ");for(int j=1;j<=ResourceNum;j++)printf("%d ",p->Max[j]);printf(" ");for( j=1;j<=ResourceNum;j++)printf("%d ",p->Allocation[j]);printf(" ");printf("%d ", p->Need[j]);printf(" ");if(i==1)for( j=1;j<=ResourceNum;j++)printf("%d ", Available[j].num);printf("\n");p=p->next;}}//安全序列求解过程显示void SafeShow(Resource Work[]){PCB *p;for(int i=1;i<=ProcessNum;i++){p=head->next;printf("%s ",Safety[i]);while(p!=NULL){if(strcmp(p->name,Safety[i])==0) break; p=p->next;}for(int j=1;j<=ResourceNum;j++) printf("%d ", WorkRecord[i][j].num); printf(" ");printf("%d ", p->Need[j]);printf(" ");for(j=1;j<=ResourceNum;j++)printf("%d ", p->Allocation[j]);printf(" ");if(i<processnum)for(int j=1;j<=ResourceNum;j++)printf("%d ", WorkRecord[i+1][j].num);elsefor(int j=1;j<=ResourceNum;j++)printf("%d ", Work[j].num);if(p->Finish) printf(" true");printf("\n");}}//进程对资源的请求void RequestResource(){void safety(PCB *head,Resource Work[],int n); char name[10];getchar();printf("请输入提出请求的进程名:\n");gets(name);PCB *p=head->next;for(int i=1;i<=ProcessNum;i++){p->Finish=false;IsSafe=false;p=head->next;PCB *pre=head;//请求进程的前驱while(p!=NULL){if(strcmp(p->name,name)==0) break;pre=p;p=p->next;}//产找请求进程的PCBprintf("请输入对资源的请求数:\n");for(i=1;i<=ResourceNum;i++)scanf("%d",&p->Request[i]);for( i=1;i<=ResourceNum;i++) //判定Requst{if(p->Request[i]>p->Need[i]||p->Request[i]>Available[i].nu m){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_RED);printf("资源数不够,不可响应请求,进程阻塞");SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_GREEN);return;}}Resource</processnum)Work[MaxResourceNum];for( i=1;i<=ResourceNum;i++){Work[i].num=Available[i].num;strcpy(Work[i].name,Available[i].name); }//试分配资源for( i=1;i<=ResourceNum;i++){Work[i].num-=p->Request[i];p->Allocation[i]+=p->Request[i];p->Need[i]-=p->Request[i];}safety(head,Work,1);//是否处于安全状态if(IsSafe){//处于安全状态进行分配for( i=1;i<=ResourceNum;i++){Available[i].num-=p->Request[i];}int end=0;for(i=1;i<=ResourceNum;i++)if(p->Need[i]==0) end++;}//若进程的Need为0,可视为其获得足够的资源,运行完成if(end==ResourceNum){printf("进程%s运行完毕",p->name);pre->next=p->next;free(p);ProcessNum--;}printf("\n");ShowStatus();}else{//处于不安全状态回退不分配SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_RED);printf("若分配,则不存在安全队列,不可响应进程%s的请求\n",name);for(int i=1;i<=ResourceNum;i++) //将之前试分配时对Allocation Need 的操作回退{p->Allocation[i]-=p->Request[i];p->Need[i]+=p->Request[i];}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HAN DLE),FOREGROUND_GREEN);ShowStatus();}}//安全性算法void safety(PCB *head,Resource Work[],int n){if(n>ProcessNum) //若进程已全部放在安全队列中,则输出安全队列{printf("进程Work Need Allocation Work+Allocation Finish \n");printf(" ");for(int k=1;k<=4;k++){for(int i=1;i<=ResourceNum;i++)printf("%s ", Available[i].name);printf(" ");}printf("\n");SafeShow(Work);printf("安全序列为:");for(int i=1;i<=ProcessNum;i++)printf("%s ",Safety[i]);printf("\n\n");IsSafe=true;}char * FoundFinish(PCB *head,Resource Work[]);PCB *p=NULL;char *c=FoundFinish(head,Work);//查找可分配资源的未完成的进程while(strcmp(c,"end")!=0) //若没有遍历完PCB链,则继续{Safety[n]=c;//插入安全序列for(int i=1;i<=ResourceNum;i++){strcpy(WorkRecord[n][i].name,Work[i].name);//记录当前Work的状态WorkRecord[n][i].num=Work[i].num;}p=head->next;for( i=1;i<=ProcessNum;i++){if(strcmp(c,p->name)==0) break;p=p->next;} //根据进程名查找PCBfor(int j=1;j<=ResourceNum;j++){Work[j].num+=p->Allocation[j];}p->Finish=true;safety(head,Work,n+1);//查找从n+1位置开始的安全子序列if(!IsSafe) break; //如果未找到,则跳出 IsSafe=falsefor(j=1;j<=ResourceNum;j++){Work[j].num-=p->Allocation[j];} //work将状态回退c=FoundFinish(p,Work); //查找在n位置的下一个满足条件的进程p->Finish=false;}}char * FoundFinish(PCB *head, Resource Work[]){ //产找满足条件的进程bool F;PCB * p=head->next;while(p!=NULL){F=true;if(!p->Finish) //Finish=false 查找未完成的进程{for(int j=1;j<=ResourceNum;j++){if(p->Need[j]>Work[j].num) //查找 need<work的进程F=false;}}else F=false;if(F) return p->name;p=p->next;}char *a={"end"}; //若从p开始的链中已无满足条件的进程则返回endreturn a;}void menu(){int n;printf("***********************银行家算法模拟**********************\n");printf("* 1.输入资源数 *\n");printf("* 2.输入个进程的资源分配情况 *\n");printf("* 3.模拟进程请求资源 *\n");printf("* 4.显示资源分配图 *\n");printf("* 5.退出 *\n");printf("******************************************************* ****\n");printf("请选择:");scanf("%d",&n);printf("\n");switch(n){case 1:PrintAvailable();break;case 2:InputPCB();break;case 3:RequestResource();break;case 4:ShowStatus();break;case 5:exit(0);break;}}int main(){while(true){menu();getchar(); getchar(); system("cls"); //清屏}return 0;}</work的进程。
银行家算法及结果

#include <iostream.h>#include <stdio.h>#include <stdlib.h>#include <string.h>//定义全局变量const int x=10,y=10; //常量,便于修改int Available[x]; //各资源可利用的数量int Allocation[y][y]; //各进程当前已分配的资源数量int Max[y][y]; //各进程对各类资源的最大需求数int Need[y][y]; //尚需多少资源int Request[x]; //申请多少资源int Work[x]; //工作向量,表示系统可提供给进程继续运行所需的各类资源数量int Finish[y]; //表示系统是否有足够的资源分配给进程,1为是int p[y]; //存储安全序列int i,j; //i表示进程,j表示资源int n,m; //n为进程i的数量,m为资源j的种类数int l=0; //l用来记录有几个进程是Finish[i]=1的,当l=n是说明系统状态是安全的int counter=0;//函数声明void chushihua(); //初始化函数void safe(); //安全性算法void show(); //函数show,输出当前状态void bank(); //银行家算法void jieshu(); //结束函数void chushihua(){cout<<"输入进程的数量: ";//从此开始输入有关数据cin>>n;cout<<"输入资源种类数: ";cin>>m;cout<<endl<<"输入各种资源当前可用的数量( "<<m<<" 种): "<<endl;for (j=0; j<m; j++){cout<<"输入资源"<<j<<" 可利用的数量Available["<<j<<"]: ";cin>>Available[j]; //输入数字的过程...Work[j]=Available[j]; //初始化Work[j],它的初始值就是当前可用的资源数}cout<<endl<<"输入各进程当前已分配的资源数量Allocation["<<n<<"]["<<m<<"]: "<<endl;for (i=0; i<n; i++){for (j=0; j<m; j++){cout<<" 输入进程"<<i<<" 当前已分配的资源"<<j<<" 数量: ";cin>>Allocation[i][j];}cout<<endl;Finish[i]=0;//初始化Finish[i]}cout<<endl<<"输入各进程对各类资源的最大需求Max["<<n<<"]["<<m<<"]: "<<endl;for (i=0; i<n; i++){for (j=0; j<m; j++){cout<<" 输入进程"<<i<<" 对资源"<<j<<" 的最大需求数: ";cin>>Max[i][j];if(Max[i][j]>=Allocation[i][j]) //若最大需求大于已分配,则计算需求量Need[i][j] = Max[i][j]-Allocation[i][j];elseNeed[i][j]=0;//Max小于已分配的时候,此类资源已足够不需再申请}cout<<endl;}cout<<endl<<"初始化完成"<<endl;}//安全性算法函数void safe(){l=0;for (i=0; i<n;i++){ //i++if (Finish[i]==0){ //逐个查找Finish[i]==0的进程条件一counter=0; //记数器for (j=0; j<m; j++){if (Work[j]>=Need[i][j]) counter=counter+1;//}if(counter==m) //i进程的每类资源都符合Work[j]>=Need[i][j] 条件二{p[l]=i; //存储安全序列Finish[i]=1; //i进程标志为可分配for (j=0; j<m;j++)Work[j]=Work[j]+Allocation[i][j]; //释放资源l=l+1; //记数,现在有L个进程是安全的,当L=N时说明满足安全序列i= -1; //从第一个进程开始继续寻找满足条件一二的进程}}}}//显示当前状态函数void show() //函数show,输出当前资源分配情况{int i,j; //局部变量int All[y]; //各种资源的总数量int L1; //局部变量L1cout<<"当前的状态为:"<<endl;cout<<"各种资源的总数量:"<<endl;for (j=0;j<m;j++){cout<<" 资源"<<j<<": ";All[j]=Available[j]; //总数量=可用的+已分配的for (i=0;i<n;i++) All[j]+=Allocation[i][j];cout<<All[j]<<" ";}cout<<endl<<"当前各种资源可用的量为(available):"<<endl;for (j=0;j<m;j++)cout<<" 资源"<<j<<": "<<Available[j]<<" ";cout<<endl<<"各进程已经得到的资源量(allocation): "<<endl;for(i=0;i<m;i++){cout<<" 资源"<<i;}cout<<endl;for(L1=0;L1<n;L1++){cout<<"进程"<<L1<<":";for (j=0;j<m;j++)cout<<Allocation[L1][j]<<" ";cout<<endl;}cout<<endl<<"各进程还需要的资源量(need):"<<endl;for(i=0;i<m;i++){cout<<" 资源"<<j;}cout<<endl;for(L1=0;L1<n;L1++){cout<<"进程"<<L1<<":";for (j=0;j<m;j++)cout<<Need[L1][j]<<" ";cout<<endl;}/* for(i=0;i<=m;i++){for (j=i;j<m;j++) cout<<" 资源"<<j;cout<<endl;for(L1=0;L1<n;L1++){cout<<"进程"<<L1<<":";for (j=i;j<m;j++)cout<<Need[L1][j]<<" ";cout<<endl;}}*/}//银行家算法函数void bank(){cout<<endl<<"进程申请分配资源:"<<endl;int k=0; //用于输入进程编号bool r=false; // 初值为假,输入Y继续申请则置为真do{//输入请求cout<<"输入申请资源的进程(0-"<<n-1<<"): ";cin>>k;cout<<endl;while(k>n-1) //输入错误处理{cout<<endl<<"输入错误,重新输入:"<<endl;cout<<endl<<"输入申请资源的进程(0--"<<n-1<<"): ";cin>>k;cout<<endl;}cout<<endl<<"输入该进程申请各类资源的数量: "<<endl;for (j=0; j<m; j++)do{ //do……while 循环判断申请输入的情况cout<<"进程"<<k<<" 申请资源["<<j<<"]的数量:";cin>>Request[j];cout<<endl;if(Request[j]>Need[k][j]){ //申请大于需求量时出错,提示重新输入(贷款数目不允许超过需求数目)cout<<"申请大于需要量!"<<endl;cout<<"申请的资源"<<j<<"的数量为"<<Request[j]<<",大于进程"<<k<<"对该资源需求量"<<Need[k][j]<<"。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("%s",p->name);
printf(" ");
for(int j=1;j<=ResourceNum;j++)
printf("%d ",p->Max[j]);
printf(" ");
for( j=1;j<=ResourceNum;j++)
gets(name);
PCB *p=head->next;
for(int i=1;i<=ProcessNum;i++)
{
p->Finish=false;
}
IsSafe=false;
p=head->next;
PCB *pre=head;//请求进程的前驱
scanf("%d",&ResourceNum);
printf("请输入资源的名称:\n");
getchar();
for(int i=1;i<=ResourceNum;i++)
{
gets(Available[i].name);
}
printf("请输入资源的数目:\n");
printf("%d ",p->Allocation[j]);
printf(" ");
for(j=1;j<=ResourceNum;j++)
printf("%d ", p->Need[j]);
printf(" ");
if(i==1)
scanf("%d",&p->Allocation[i]);
printf("推得需求向量为:");
for( i=1;i<=ResourceNum;i++)
{
p->Need[i]=p->Max[i]-p->Allocation[i];
printf(" %d",p->Need[i]);
}
p->next=NULL;
p->Finish=false;
printf("\n");
getchar();
tail->next=p;
tail=p;
}
PCB *p=head->next;
for( i=1;i<=ProcessNum;i++)
PCB *p;
for(int i=1;i<=ProcessNum;i++)
{
p=head->next;
printf("%s ",Safety[i]);
while(p!=NULL)
{
if(strcmp(p->name,Safety[i])==0) break;
{
for(int j=1;j<=ResourceNum;j++)
Available[j].num-=p->Allocation[j];
p=p->next;
}
printf("\n");
CurrentCheck();
printf("\n");
ShowStatus();
for(i=1;i<=ResourceNum;i++)
scanf("%d",&Available[i].num);
}
//输入进程的资源情况
void InputPCB(){
void ShowStatus() ;
void CurrentCheck();
printf("请输入进程数");
typedef struct PCB{
char name[10]; //进程名
char status[10]; //状态
int Max[MaxResourceNum]; //最大需求向量
int Allocation[MaxResourceNum]; //分配向量
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
printf("资源数不够,不可响应请求,进程阻塞");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
scanf("%d",&ProcessNum);
getchar();
printf("输入%d个进程的资源分配情况:\n",ProcessNum);
for(int i=1;i<=ProcessNum;i++)
{
PCB *p=(PCB *)malloc(sizeof(PCB));
Resource WorkRecord[MaxProcessNum][MaxResourceNum]; //查找安全序列时的Word记录
int ResourceNum,ProcessNum; //资源数,进程数
bool IsSafe=false; //当前或满足进程请求后状态是否安全
scanf("%d",&p->Request[i]);
for( i=1;i<=ResourceNum;i++) //判定Requst<Need request<Available是否成立
{
if(p->Request[i]>p->Need[i]||p->Request[i]>Available[i].num)
printf(" ");
for(j=1;j<=ResourceNum;j++)
printf("%d ", p->Allocation[j]);
printf(" ");
if(i<ProcessNum)
for(int j=1;j<=ResourceNum;j++)
char * Safety[MaxProcessNum];//安全序列
typedef struct Resource{ //资源结点
char name[10]; //名称
int num; //数量
}Resource;
Resource Available[MaxResourceNum]; //可利用资源向量
int Need[MaxResourceNum]; //需求向量
int Request[MaxResourceNum]; //请求向量
bool Finish; //进程是否获得资源已完成
struct PCB *next; //下一个结点
}
}
//显示当前资源分配状态
void ShowStatus()
{
printf("当前系统状态:\n");
printf(" Max Allocation Need Available \n");
printf(" ");
for(int k=1;k<=4;k++){
for(int i=1;i<=ResourceNum;i++)
printf(" %s ",Available[i].name);
printf(" ");}
printf("\n");
PCB *p=head->next;
for(int i=1;i<=ProcessNum;i++)
for( j=1;j<=ResourceNum;j++)
printf("%d ", Available[j].num);
printf("\n");
p=p->next;
}
}
//安全序列求解过程显示
void SafeShow(Resource Work[])
{
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
printf("当前时刻系统处于不安全状态,请重新设置\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
printf("请输入进程名:");
gets(p->name);
printf("输入最大需求向量:");
for(int i=1;i<=ResourceNum;i++)
scanf("%d",&p->Max[i]);
printf("输入分配向量:");