银行家算法.docx
《银行家算法.docx》由会员分享,可在线阅读,更多相关《银行家算法.docx(19页珍藏版)》请在冰豆网上搜索。
![银行家算法.docx](https://file1.bdocx.com/fileroot1/2023-1/6/c29f06fe-8214-4343-821a-ec0b66998308/c29f06fe-8214-4343-821a-ec0b669983081.gif)
银行家算法
淮海工学院计算机科学系
实验报告书
课程名:
《操作系统原理》
题目:
银行家算法
班级:
学号:
姓名:
一、目的与要求:
1)本实验目的是通过使用银行家算法实现系统资源的分配和安全性检查模拟,提高学生对操作系统资源分配功能的深刻理解,并培养学生对操作系统开发的兴趣与应用能力;
2)实验前必须认真阅读和理解银行家算法的基本原理和实现方法;
3)独立使用C或VC++编程语言编写银行家算法模拟程序;
4)按照实验题目要求独立正确地完成实验内容(编写、调试算法程序,提交程序清单及及相关实验数据与运行结果)
二、实验内容或题目
1)设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源总数量分别为10,5,7。
(参考书上用例)
2)并行进程可动态地申请资源和释放资源(程序交互输入申请或释放资源数量),系统按各进程的申请动态地分配资源。
3)每当进程动态申请资源或释放资源时,模拟程序应能及时显示或打印各个进程在此时刻的资源分配表、系统可用资源量和安全序列等资源分配信息和安全检查信息。
4)本次实验内容(项目)的详细说明以及要求请参见实验指导书。
三、实验步骤与源程序
1.实验步骤
①理解银行家算法
②构造进程和系统资源的数据结构
③确定本次实验主要实现的一些功能,如何实现,打算怎么实现
④用java编写代码
⑤修改,优化
2.源代码
importjava.util.*;
importjava.util.Queue;
importjava.util.LinkedList;
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
importjavax.swing.JOptionPane;
classprocess
{
intID;//编号
intneed[];//资源需求数组
intmax[];//资源最大需求
intallocation[];//资源分配数组
booleanfinish=false;
process(intID,inta)//构造函数初始化对象
{
this.ID=ID;
need=newint[a];
max=newint[a];
allocation=newint[a];
}
}
classAvailable//系统资源
{
intcount;//资源的总量
intsurplus;//可用资源数量
Available(intcount)
{
this.count=count;
}
}
classMyTableextendsJTable
{
MyTable(Objecta[][],Objectname[])
{
super(a,name);
}
publicbooleanisCellEditable(introw,intcol)//重写该方法使表格的第一列不可编辑
{
if(col==0)
{returnfalse;}
else
{returntrue;}
}
}
classwinextendsJFrameimplementsActionListener,TextListener
{
JButtonbtn,btn1,btn3;
JTextAreata;
JPanelp1,p2,p3;
JLabellabel1,label2;
process[]p;//进程数组
Stringss=null;
intnum=0,n=0;
StringBufferb=newStringBuffer("进程\\资源状况\tWork\tNeed\tAllocationWork+Allocation\tFinish@");//存储安全序列的详细信息
Containercon;
Availableava[];//系统资源数组
booleanbl=false;
TextFieldt[]=newTextField[2];
MyTabletable;
Objecta[][];
JScrollPanejp;
Objectname[];
intlabel=0;
win(Strings)
{
super(s);
for(inti=0;i<2;i++)
{
t[i]=newTextField(10);
}
label1=newJLabel("进程数量");
label2=newJLabel("资源种类数量");
p1=newJPanel();
p1.add(label1);
p1.add(t[0]);
p1.add(label2);
p1.add(t[1]);
ta=newJTextArea(10,30);
btn=newJButton("Submit");
p1.add(btn);
con=getContentPane();
con.add(p1,BorderLayout.NORTH);
p2=newJPanel();
btn1=newJButton("Start");
btn1.setEnabled(false);//进程运行按钮设置为非激活
btn1.addActionListener(this);
p2.add(btn1);
for(inti=0;i<2;i++)
{
t[i].addTextListener(this);
}
btn.addActionListener(this);
btn3=newJButton("Sure");
btn3.addActionListener(this);
con.add(btn3,BorderLayout.SOUTH);
setVisible(true);
setBounds(200,200,500,500);
setResizable(false);//窗口大小不可变
addWindowListener(newWindowAdapter()
{
publicvoidwindowClosing(WindowEvente)
{
System.exit(0);
}
});
validate();
}
publicbooleanisNumeric(Stringstr)//判断文本框中的内容是否为数字
{
for(inti=str.length();--i>=0;)
{
if(!
Character.isDigit(str.charAt(i)))
{
returnfalse;
}
}
returntrue;
}
publicbooleanrequest(process[]p,intn,intnum,Available[]ava,Stringss)//进程向系统请求资源
{
Stringsp=null;
inta[]=newint[num+1];
intj=0,i=0;
if(ss.equals("Y")||ss.equals("y"))//进程ID和各资源的请求量随机产生
{
for(i=0;i{
if(i==0)
{
a[i]=(int)(Math.random()*n+1);//随机选择一个进程
}
else
{
a[i]=(int)(Math.random()*ava[j++].count);//随机产生对每个资源的请求量
}
}
}
else//自定义输入
{
i=0;
try
{
sp=JOptionPane.showInputDialog(this,"请分别输入进程ID与资源的请求量,用逗号隔开");
}
catch(Exceptionex){}
StringTokenizerfenxi=newStringTokenizer(sp,",");
while(fenxi.hasMoreTokens())
{
a[i++]=Integer.parseInt(fenxi.nextToken());
}
}
ta.setText(null);
ta.append("当前请求资源的进程编号为:
"+a[0]+"\n");
i=1;
ta.append("请求资源量为:
(");
for(;i{
ta.append(""+a[i]);
if(i!
=num)
{
ta.append(",");
}
}
ta.append(")\n");
booleanbs=true,bd=true;
for(i=1;i{
if(p[a[0]-1].need[i-1]{
bd=false;
}
}
for(i=0;i{
if(a[i+1]>ava[i].surplus)
{
bs=false;
}
}
if(!
bs&&!
bd)
{
returnfalse;
}
else
{
i=1;j=0;
for(;i{
ava[j].surplus-=a[i];
if(ava[j].surplus<0)
{
JOptionPane.showMessageDialog(this,"当前资源无法满足该进程的请求");
break;
}
else
{j++;}
}
for(i=0;i{
p[a[0]-1].need[i]-=a[i+1];
p[a[0]-1].allocation[i]+=a[i+1];
}
if(j==num)
{returntrue;}
else{returnfalse;}
}
}
@SuppressWarnings("unchecked")
publicvoidcheckSafe(process[]p,Available[]ava,StringBufferb,intn,intnum)
{
Queuequeue=newLinkedList();//安全队列
intq[]=newint[num];
for(inti=0;i{q[i]=ava[i].surplus;}
intx=0;
for(inti=0;i{
for(intj=0;j{
x=0;
for(intk=0;k{
if(p[j].need[k]<=q[k]&&!
p[j].finish)//当前进程对当前资源的需求小于系统可用资源量
{x++;}
else{break;}
}
if(x==num)//系统可用资源满足当前的进程
{
p[j].finish=true;//当前进程的请求,系统资源满足,改变其Finish属性
b.append(""+p[j].ID+"\t");//将该进程的信息存入变量b中
for(intm=0;m{
b.append(""+q[m]+"");
}
b.append("\t");
for(intm=0;m{
b.append(""+p[j].need[m]+"");
}
b.append("\t");
for(intm=0;m{
b.append(""+p[j].allocation[m]+"");
}
b.append("\t");
for(intm=0;m{
q[m]+=p[j].allocation[m];
b.append(""+(q[m])+"");
}
b.append("\t"+p[j].finish+"@");
queue.offer(p[j]);//加入安全队列
break;//重头扫描
}
}
}
x=0;
for(inti=0;i{
if(!
p[i].finish)//判断每个进程的Finish属性
{
JOptionPane.showMessageDialog(this,"不存在安全序列!
");
break;
}
else{x++;}
}
if(x==n)//进程的finish全为true,即存在安全序列
{
StringBuffery=newStringBuffer("");
for(inti=0;i{
y.append("P"+((process)queue.element()).ID+"");
queue.remove();
}
JOptionPane.showMessageDialog(this,"存在安全序列:
"+newString(y));
Strings=newString(b);
StringTokenizerfenxi=newStringTokenizer(s,"@");
while(fenxi.hasMoreTokens())//显示资源分配表和安全序列
{
ta.append(fenxi.nextToken()+"\n");
}
}
}
publicprocess[]needofA(intn,intnum,process[]p,MyTabletable)//计算每个进程完成还需的每个资源的数量
{
intk=1;
for(inti=0;i{
k=1;
for(intj=0;j{
p[i].max[j]=Integer.parseInt((String)a[i][k]);
p[i].allocation[j]=Integer.parseInt((String)a[i][k+1]);
k=k+2;j++;
}
}
for(inti=0;i{
k=0;
for(intj=1;j<(2*num+1);)
{
intx=Integer.parseInt((String)a[i][j]);
inty=Integer.parseInt((String)a[i][j+1]);
p[i].need[k++]=(x-y);
j=j+2;
if(j>2*num)
break;
}
}
returnp;
}
publicvoidactionPerformed(ActionEvente)
{
if(e.getSource()==btn)//显示表格
{
a=newObject[n][2*num+1];
for(inti=0;i{
for(intj=0;j<2*num+1;j++)
{
if(j!
=0)
a[i][j]="0";
else
a[i][j]="进程"+(i+1);
}
}
name=newObject[2*num+1];
intj=0;
for(inti=0;i<2*num+1;)
{
if(i==0)
{
name[i]="进程编号";
i++;
}
else
{
name[i]="MaxFor资源"+(++j);
name[i+1]="HavaFor资源"+(j);
i+=2;
}
}
table=newMyTable(a,name);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);//当调整表的大小时,设置表的自动调整模式为不自动调整列的宽度,使用滚动条
table.setCellSelectionEnabled(true);//设置此表允许同时行选择
jp=newJScrollPane(table);
con.add(jp,BorderLayout.CENTER);
btn.setEnabled(false);
t[0].setEnabled(false);
t[1].setEnabled(false);
validate();
}
if(e.getSource()==btn1)//进程创建完成,开始运行
{
if(label<1)//第一次运行
{
con.remove(jp);
con.add(ta,BorderLayout.CENTER);
validate();
}
label++;//执行次数
if(!
request(p,n,num,ava,ss))
{
System.out.println("212");
JOptionPane.showMessageDialog(this,"当前系统可利用资源无法满足进程的需求!
");
}
else
{
checkSafe(p,ava,b,n,num);//安全序列
}
btn1.setEnabled(false);
}
if(e.getSource()==btn3)
{
needofA(n,num,p,table);//计算每种资源的需求量
for(inti=0;i{
intsum=ava[i].count;
for(intj=0;j{
sum-=p[j].allocation[i];
}
ava[i].surplus=sum;
}
btn1.setEnabled(true);
con.remove(btn3);
con.add(p2,BorderLayout.SOUTH);
validate();
ss=JOptionPane.showInputDialog(this,"进程与请求随机产生清输入Y,自定义请输入N!
");
}
}
publicvoidtextValueChanged(TextEvente)
{
if(e.getSource()==t[1])
{
try
{
if(isNumeric(t[1].getText()))
{
Strings1=JOptionPane.showInputDialog("请分别输入"+t[1].getText()+"个系统资源的总量,用逗号隔开");
StringTokenizerfenxi=newStringTokenizer(s1,",");
num=fenxi.countTokens();
inti=0;
ava=newAvailable[num];
while(fenxi.hasMoreTokens())
{
Strings=fenxi.nextToken();
if(isNumeric(s))
{
ava[i++]=newAvailable(Integer.parseInt(s));//创建系统资源
}
else
{
JOptionPane.showMessageDialog(this,"系统资源数目不能为字符!
");
break;
}
}
p=newprocess[Integer.parseInt(t[0].getText())];
for(i=0;i{
p[i]=newprocess(i+1,num);//创建进程
}
}
else
{
JOptionPane.showMessageDialog(this,"系统种类数不能为字符!
");
}
}
catch(Exceptione0){}
}
if(e.getSource()==t[0])
{
try
{
if(t[0].getText().length()<1)
{
JOptionPane.showMessageDialog(this,"进程数不能为空!
");
}
if(isNumeric(t[0].getText()))
{n=Integer.parseInt(t[0].getText());}
else
{JOptionPane.showMessageDialog(this,"进程数只能为数字!
");}
}catch(Exceptionee){}
}}}
publicclassbanker
{
publicstaticvoidmain(Stringa[])
{newwin("银行家算法");}
}
四、测试数据与实验结果