银行家算法_操作系统
一、实验内容
编制模拟银行间算法的程序,并以下面给出的例子验证所编写的程序的正确性。
例3-1 某系统有A、 B、 C、 D4类资源共5个进程(P0、 P1、 P2、 P3、 P4)共享, 1各进程对资源的需求和分配情况如表3 - 1所示。
现在系统中A、 B、 C、 D4类资源分别还剩1、5、2、 0个,请按银行家算法回答下列问题:
① 现在系统是否处于安全状态?
②如果现在进程P1提出需要(o、4、2、 0)个资源的请求,系统能否满足它的
在该实验中涉及银行家算法和安全检査性算法;- 下事:分 别对两种算法作具体的介绍 。
二、实验准备
1.银行家算法
在避免死锁的方法中, 如果所施加的限制条件较弱, 有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状系度可以避免发生死锁。
.
基本思想是分配资源之前,判断系统是否是安全的;若安全,才分配。它是最具有代.生的避免死锁的算法,具体算法如下表示:
假设进程 P提出请求 Request[i],则银行家算法按如下步骤进行判断。
Step1:如果Request[i]<=Need[i],则转向 Step2;否则,出错
Step2:如果Request[i]<=Available[i],则转向 Step3;否则, 出错。
Step3:系统试探分配相关资源,修改相关数据:
Available[i]=Available[i]-Request[i] , …
Available[i]=Available[i]+ Request[i] ,
Need[i]=Need[i]- Request[i] ,
SteP4:系统执行安全性检査,如安全,则分配成立;否则试探性分配资源作废,系名次复原状 进程进人等待态。
:’
根据以上的银行家算法步骤, 可得出如图所示3-1的银行家算法程序流程图 。
如图3 -1银行家算法程序流程图 。
2.安全性检查算法
安全性检查算法主要是根据银行家算法进行资源分配后,检查资源分配后的系统状态是否处于安全状态之中。具体算法如下所示:
step1: 设置两个工作向量 Work=Available, Finish=false;
step2 : 从进程集合中找到一个满足下述条件的进程;
Finish=false,
Need<=Work,
如果能够找到该进程, 则执行 Step3, 否则, 执行 Step4;
Step3:假设上述找到的进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work十A:L1ocation,
Finish=true,
Goto Step2;
Step4:如果所有进程的 Finish=true,则表示该系统安全;否则系统不安全。
根据以上安全性检査算法的步骤, 可得出如图3 - 2所示的安全性检査算法程序流程图 。
如图3 - 2安全性检査算法程序流程图 。
三、实验截图
三、程序源代码 - -Java- -
package jincheng;
class Pid{
static char[]resource;//资源类别
static int[]available;//现在剩余资源
int[]request;//申请资源数量
{
request=new int [Pid.resource.length];
}
boolean finish;
{
finish=false;
}
int[]allocation;//已经占用资源
int[]maxneed;//进程所需要最大资源
int[]need;//进程现在需要资源
{
allocation=new int [Pid.resource.length];
maxneed=new int [Pid.resource.length];
need=new int [Pid.resource.length];
}
//初始化
public Pid(int[] allocation, int[] maxneed) {
this.allocation = allocation;
this.maxneed = maxneed;
}
public int[] getRequest() {
return request;
}
public void setRequest(int[] request) {
this.request = request;
}
public int[] getAllocation() {
return allocation;
}
public int[] getMaxneed() {
return maxneed;
}
public void show() {
for(int a:this.getAllocation()) {
System.out.print(a +" ");
}
}
}
public class BankDemo426 {
static int []x=new int[5];
public static void main(String[] args) {
//静态 资源类别资源剩余数量初始化
char []res= {'A','B','C','D'};Pid.resource=res;
int len=Pid.resource.length;
int []ava= {1,5,2,0};Pid.available=ava;
//占用资源allocation最大资源maxneed初始化
int []a0= {0,0,1,2};int[]b0= {0,0,1,2};Pid p0=new Pid(a0,b0);
int []a1= {1,0,0,0};int[]b1= {1,7,5,0};Pid p1=new Pid(a1,b1);
int []a2= {1,3,5,4};int[]b2= {2,3,5,6};Pid p2=new Pid(a2,b2);
int []a3= {0,6,3,2};int[]b3= {0,6,5,2};Pid p3=new Pid(a3,b3);
int []a4= {0,0,1,4};int[]b4= {0,6,5,6};Pid p4=new Pid(a4,b4);
//申请资源request初始化
int []c1= {0,4,2,0};p1.setRequest(c1);
Pid []p=new Pid[5];
//进程加载p
p[0]=p0;p[1]=p1;p[2]=p2;p[3]=p3;p[4]=p4;
//need ins
for (Pid pi:p) {
for(int j=0;j<len;j++)
pi.need[j]=pi.maxneed[j]-pi.allocation[j];
}
if(bankFun(p,1)) {
System.out.println("--分配成立");
System.out.print("安全顺序:");
for(int px:x) {
System.out.print("p"+px+" ");
}
}
else
System.out.println("--分配失败");
}
//银行家算法
public static boolean bankFun(Pid []p,int n) {
int len=Pid.resource.length;
//step1 Request[i]<=Need[i]
for (int i = 0; i < len; i++) {
if(p[n].request[i]>p[n].need[i]) {
System.out.println("--Request[i]<=Need[i] error");
return false;
}
}
System.out.println("1.Request[i]<=Need[i]");
//step2 Request[i]<=Available[i]
for (int i = 0; i < len; i++) {
if(p[n].request[i]>Pid.available[i]) {
System.out.println("--Request[i]<=Available[i] error");
return false;
}
}
System.out.println("2.Request[i]<=Available[i]");
//step3 系统试探分配相关资源
int []memava=Pid.available;
int []memall=p[n].allocation;
int []memnee=p[n].need;
for(int i=0;i<len;i++) {
Pid.available[i]-=p[n].request[i];
p[n].allocation[i]+=p[n].request[i];
p[n].need[i]-=p[n].request[i];
}
System.out.println("3.系统试探分配相关资源");
//setp4 系统执行安全性检査
System.out.println("4.系统执行安全性检査");
if(safeFun(p)) {
return true;
}
else {
System.out.println("--失败 已恢复");
Pid.available=memava;
p[n].allocation=memall;
p[n].need=memnee;
return false;
}
}
public static boolean safeFun(Pid []p) {
int len=Pid.resource.length;
/*数据 检测
for(Pid pi:p) {
for (int i = 0; i < pi.need.length; i++) {
System.out.print(pi.need[i]);
}
System.out.println();
}
for(Pid pi:p) {
for (int i = 0; i < pi.allocation.length; i++) {
System.out.print(pi.allocation[i]);
}
System.out.println();
}
*/
//setp1 Work=Available, Finish=false;
int []work=Pid.available;
System.out.println("a.Work=Available, Finish=false;");
//setp2 Finish=false;Need<=Work;
for(int i=0,k=0;i<p.length;i++) {
if(!p[i].finish&&cheekNK(p[i],work)) {
System.out.println("b.可以执行p"+i);
//step3 顺利执行,直至完成,从而释放资源
for(int j=0;j<len;j++) {
work[j]+=p[i].allocation[j];
}
p[i].finish=true;
System.out.println("c.p"+i+"顺利执行,释放资源");
x[k]=i;k++;
i=0;
}
}
//step4 所有进程的 Finish=true
System.out.println("d.进程安全检测");
for(Pid pi:p) {
if(!pi.finish) {
System.out.println("--有进程不能执行");
System.out.println("--不安全");
return false;
}
}
System.out.println("--所有进程的 Finish=true");
System.out.println("--安全");
return true;
}
public static boolean cheekNK(Pid pi,int []work) {
for(int i=0;i<pi.need.length;i++) {
if(pi.need[i]>work[i]) {
return false;
}
}
return true;
}
}