PCB*h=newPCB;
create(h);
while(h->next!
=NULL)
{
call(h);
sort(h);
show(h);
}
}
实验二银行家算法实验
一、实验目的
熟悉银行家算法,理解系统产生死锁的原因及避免死锁的方法,加深记意。
二、实验要求
用高级语言编写和调试一个描述银行家算法的程序。
设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源数量分别为10,5,7。
进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。
要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。
三、实验原理
利用银行家算法避免死锁
1、银行家算法中的数据结构
(1)可利用资源向量Available
(2)最大需求规阵Max
(3)分配矩阵Allocation
(4)需求矩阵Need
2、银行家算法
(1)如果Requesti<或=Need,则转向步骤2;否则,认为出错,因为它所需要的资源数已超过它所宣布的最大值。
(2)如果Request<或=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,P1必须等待。
(3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的数值:
Available:
=Available-Requesti;
Allocation:
=Allocationi+Request;
Needi:
=Needi-request;
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
3、安全性算法
系统所执行的安全性算法可描述如下:
(1)设置两个向量
①工作向量Work。
它表示系统可提供进程继续运行所需要的各类资源数目,它含有m个元素,执行安全算法开始时,Work:
=Allocation;
②Finish。
它表示系统是否有足够的资源分配给进程,使之运行完成,开始时先做Finish[i]:
=false;当有足够资源分配给进程时,令Finish[i]:
=true。
(2)从进程集合中找到一个能满足下述条件的进程:
①Finish[i]:
=false
②Need=Work
如找到,执行步骤(3);否则,执行步骤(4)。
(3)当进程P获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work:
=Work+Allocation;
Finish[i]:
=true;
Gotostep2;
(4)如果所有进程的Finish[i]=true,则表示系统处于安全状态;否则,系统处于不安全状态。
4、银行家算法之例
假设有五个进程{P0,P1,P2,P3,P4}和三种类型的资源{A,B,C},每一种资源的数量分别为10、5、7,在T0时刻的资源分配情况如图1所示。
图1
(1)T0时刻的安全性
利用安全性算法对T0时刻的资源分配情况进行分析,可得下表所示的T0时刻的安全性分析,从中得知,T0时刻存在着一个安全序列{P1,P3,P4,P2,P0},故系统是安全的,如图2所示。
图2
(2)P1请求资源
P1发出请求向量Request(1,0,2),系统按银行家算法进行检查:
(1)Request1(1,0,2)≤Need(1,2,2)
(2)Request1(1,0,2)≤Available(3,3,2)
(3)系统先假定可为P1分配资源,并修改Aailable,Allocation1和Need1向量,由此形成的资源变化情况如图1中的圆括号所示。
(4)我们再利用安全性检查此时系统是否安全。
由所进行的安全性检查得知,可以找到一个安全序列{P1,P3,P4,P2,P0}。
因此,系统是安全的,可以立即将P1所申请的资源分配给它。
(3)P4请求资源
P4发出请求向量Request(3,3,0),系统按银行家算法进行检查:
(1)Request4(3,3,0)≤Need4(4,3,1)。
(2)Request4(3,3,0)>Available(2,3,0),让P4等待。
(4)P0请求资源
P0发出请求向量Request0(0,2,0),系统按银行家算法进行检查:
(1)Request0(o,2,0)<或=Need0(7,4,3));
(5)进行安全性检查
可用资源Available{2,1,0}已不能满足任何进程的需要,故系统进入不安全状态,此时系统不分配资源。
如果在银行家算法中,把P0发出的请求向量改为Request(0,1,0),系统是否能将资源分配给它,请读者考虑
四、实验所需仪器、设备、材料
PC机
五、实验思路
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。
它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST[i],则银行家算法按如下规则进行判断。
(1)如果REQUEST[cusneed][i]<=NEED[cusneed][i],则转
(2);否则,出错。
(2)如果REQUEST[cusneed][i]<=AVAILABLE[cusneed][i],则转(3);否则,出错。
(3)系统试探分配资源,,进
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状程等待
安全性检查算法
(1)设置两个工作向量Work=AVAILABLE;FINISH
(2)从进程集合中找到一个满足下述条件的进程,FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work+=ALLOCATION;
Finish=true;
(4)如所有的进程Finish=true,则表示安全;否则系统不安全
六、实验结果
#include
usingnamespacestd;
#include
#include
#defineFalse0
#defineTrue1
intMax[100][100]={0};//各进程所需各类资源的最大需求
intAvaliable[100]={0};//系统可用资源
charname[100]={0};//资源的名称
intAllocation[100][100]={0};//系统已分配资源
intNeed[100][100]={0};//还需要资源
intRequest[100]={0};//请求资源向量
inttemp[100]={0};//存放安全序列
intWork[100]={0};//存放系统可提供资源
intM=100;//作业的最大数为100
intN=100;//资源的最大数为100
voidshowdata()//显示资源矩阵
{
inti,j;
cout<<"系统目前可用的资源[Avaliable]:
"<for(i=0;icout<cout<for(j=0;jcout<cout<cout<<"MaxAllocationNeed"<cout<<"进程名";
for(j=0;j<3;j++){
for(i=0;icout<cout<<"";
}
cout<for(i=0;icout<<""<
for(j=0;jcout<cout<<"";
for(j=0;jcout<cout<<"";
for(j=0;jcout<cout<}
}
intsafe()//安全性算法
{
inti,k=0,m,apply,Finish[100]={0};
intj;
intflag=0;
Work[0]=Avaliable[0];
Work[1]=Avaliable[1];
Work[2]=Avaliable[2];
for(i=0;iapply=0;
for(j=0;jif(Finish[i]==False&&Need[i][j]<=Work[j]){
apply++;//只有apply为n时才能进行分配
if(apply==N){
for(m=0;mWork[m]=Work[m]+Allocation[i][m];//变分配数
Finish[i]=True;//把完成的进程标志位1
temp[k]=i;//记录符合条件的是哪一组
i=-1;
k++;
flag++;
}
}
}
}
for(i=0;iif(Finish[i]==False){
cout<<"系统不安全"<return-1;
}
}
cout<<"系统是安全的!
"<cout<<"分配的序列:
";
for(i=0;icout<if(i";
}
cout<return0;
}
intmain()//主函数
{
inti,j,number,m,n,flag;
charming;
cout<<"请首先输入系统可供资源种类的数量:
";
cin>>n;
N=n;
for(i=0;i{
cout<<"资源"<
";
cin>>ming;
name[i]=ming;
cout<<"资源的数量:
";
cin>>number;
Avaliable[i]=number;
}
cout<cout<<"请输入作业的数量:
";
cin>>m;
M=m;
cout<<"请输入各进程的最大需求量("<"<for(i=0;ifor(j=0;jcin>>Max[i][j];
do{
flag=0;
cout<<"请输入各进程已经申请的资源量("<"<for(i=0;ifor(j=0;jcin>>Allocation[i][j];
if(Allocation[i][j]>Max[i][j])
flag=1;
Need[i][j]=Max[i][j]-Allocation[i][j];
}
if(flag)
cout<<"申请的资源大于最大需求量,请重新输入!
\n";
}
while(flag);
showdata();//显示各种资源
safe();//用银行家算法判定系统是否安全
return1;
}
实验3:
主存储器空间的分配和回收
3.1实验目的
一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实验帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
3.2实验要求
1.在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。
2.打印空闲区说明表的初始状态,作业4的申请量以及为作业4分配后的空闲区说明表状态;再依次打印作业3和作业2的归还量以及回收作业3,作业2所占主存后的空闲区说明表。
3.3实验原理和设计
1.可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。
随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。
例如:
0
5k
10k
14k
26k
32k
128k
操作系统
作业1
作业3
空闲区
作业2
空闲区
其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
3.4实验结果
附加程序
#include
usingnamespacestd;
intTABLE[4][2]={{0,512}};//TABLE[][]={起始地址,长度}
intWORK[8][3]={{300,1,0},{100,2,0},{300,1,1},{150,3,0},{30,4,0},{40,5,0},{60,6,0},{30,4,1}};
//WORKE[][]={作业大小,作业次序/起始地址,操作类型(0申请/1释放)}
inti,j,k,flag=1,now,temp[2],once=0;//now当前作业,temp[2]交换变量,once执行申请变量,i,j,k循环变量
voidfirst_01()//TABLE功能的实现:
申请作业功能
{
once=0;
for(i=0;i{
if(once==0&&TABLE[i][1]>=WORK[now][0])
{
TABLE[i][0]=TABLE[i][0]+WORK[now][0];
TABLE[i][1]=TABLE[i][1]-WORK[now][0];
for(j=now;j<8;j++)
{
if(WORK[j][2]==1&&WORK[now][2]==0&&WORK[j][1]==WORK[now][1])
{
WORK[j][1]=TABLE[i][0];//释放作业的起始地址
WORK[now][1]=TABLE[i][0]-WORK[now][0];//申请作业的起始地址
}
}
once=1;
}
}
}
voidfirst_02()//TABLE功能的实现:
释放作业功能
{
j=0;
for(i=0;i{
if(WORK[now][1]==TABLE[i][0])//初始地址重复
{
TABLE[i][0]=TABLE[i][0]-WORK[now][0];
TABLE[i][1]=TABLE[i][1]+WORK[now][0];
}
else
{
j++;
}
}
if(j==flag)
{