操作系统课程设计实验报告用C++实现银行家算法由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“银行家算法c实验报告”。
操 作 系 统
实 验 报 告
(2)学院:计算机科学与技术学院 班级:计091 学号:姓名: 时间:2011/12/30
目 录
1.实验名称……………………………………………………3 2.实验目的……………………………………………………3 3.实验内容……………………………………………………3 4.实验要求……………………………………………………3 5.实验原理……………………………………………………3 6.实验环境……………………………………………………4 7.实验设计……………………………………………………4 7.1数据结构设计……………………………………………………………………4 7.2算法设计…………………………………………………………………………6 7.3功能模块设计……………………………………………………………………7 8.实验运行结果………………………………………………8 9.实验心得……………………………………………………9
附录:源代码(部分)…………………………………………………………………9
一、实验名称:
用C++实现银行家算法
二、实验目的:
通过自己编程来实现银行家算法,进一步理解银行家算法的概念及含义,提高对银行家算法的认识,同时提高自己的动手实践能力。
各种死锁防止方法能够阻止发生死锁,但必然会降低系统的并发性并导致低效的资源利用率。死锁避免却与此相反,通过合适的资源分配算法确保不会出现进程循环等待链,从而避免死锁。本实验旨在了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生。
三、实验内容:
利用C++,实现银行家算法
四、实验要求:
1.完成银行家算法的设计
2.设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。
五、实验原理:
系统中的所有进程放入进程集合,在安全状态下系统收到进程的资源请求后,先把资源试探性的分配给它。之后,系统将剩下的可用资源和进程集合中的其他进程还需要的资源数作比较,找出剩余资源能够满足的最大需求量的进程,从而保证进程运行完毕并归还全部资源。这时,把这个进程从进程集合中删除,归还其所占用的所有资源,系统的剩余资源则更多,反复执行上述步骤。最后,检查进程集合,若为空则表明本次申请可行,系统处于安全状态,可以真正执行本次分配,否则,本次资源分配暂不实施,让申请资源的进程等待。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。要解释银行家算法,必须先解释操作系统安全状态和不安全状态。安全序列是指一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj(j
安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。
不安全状态:不存在一个安全序列。不安全状态不一定导致死锁。
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2)顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4)当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。
六、实验环境:
Win-7系统
Visual C++ 6.0
七、实验设计:
1.数据结构设计 定义结构体:
struct Proce//进程属性构成 { Source claim;//进程最大需求量
Source allocation;//进程占有量
Source claim_allocation;//进程需求量
Source currentAvail;//进程可获得量 };
定义类对象:
cla Source //资源的基本构成以及功能 {
private: public: int R1;//定义三类类资源
int R2;int R3;
Source(int r1 = 0,int r2 = 0,int r3 = 0){ R1=r1;R2=r2;R3=r3;}
Source(Source& s){ R1=s.R1;R2=s.R2;R3=s.R3;}
void setSource(int r1 = 0,int r2 = 0,int r3 = 0)//设置各类资源
{ R1=r1;R2=r2;R3=r3;}
void add(Source s)//加法
{ R1=R1+s.R1;R2=R2+s.R2;R3=R3+s.R3;}
void sub(Source s)//减法
{ R1=R1-s.R1;R2=R2-s.R2;R3=R3-s.R3;}
bool lower(Source s)//比较
{
if(R1 > s.R1)return false;
if(R2 > s.R2)return false;
if(R3 > s.R3)return false;
return true;} };
cla Data//封装所有数据 { public: Proce *p;//进程指针
Source sum;//总资源量
Source available;//可获得量
Source ask;//请求量
int pLength;//进程个数
int * ruler;//逻辑尺
void clearProce()//进程currentAvail清零
{
for(int i=0;i
{ p[i].currentAvail.setSource(0, 0, 0);} } };
cla DataInit//封装初始化数据函数类 { private: public: DataInit()//构造函数
{ }
void initLength(Data *db)//设置进程个数
{
int n;
cout
cin>>n;
db->pLength = n;
db->p = new Proce[n];
if(!db->p)
{cout
db->ruler = new int[n];
if(!db->ruler)
{cout
2.算法设计
cla FindSafeList//寻找安全序列 { private: public: FindSafeList()//构造函数
{}
bool checkList(Data *db)//检查一个序列安全性
{
int i=0;//i用于循环
db->p[db->ruler[i]].currentAvail.add(db->available);//将当前系统可用资源量赋给该序列的第一个进程
if(!db->p[db->ruler[i]].claim_allocation.lower(db->p[db->ruler[i]].currentAvail))//若当前进程currentAvail小于该进程需求量(claim-allocation),返回false
{return false;}
for(i=1;ipLength;i++)
{
//当前进程的可获得资源量currentAvail获得前一个进程的未释放资源前可获得资源量currentAvail
db->p[db->ruler[i]].currentAvail.add(db->p[db->ruler[i-1]].currentAvail);
//当前进程的可获得资源量currentAvail获得前一个进程的释放的资源量
db->p[db->ruler[i]].currentAvail.add(db->p[db->ruler[i-1]].allocation);
//若当前进程currentAvail小于该进程需求量(claim-allocation),返回false
if(!db->p[db->ruler[i]].claim_allocation.lower(db->p[db->ruler[i]].currentAvail))
{ return false;}
//若当前进程currentAvail大于该进程总资源量,返回false
if(!db->p[db->ruler[i]].currentAvail.lower(db->sum))
{ return false;}
}
return true;//该序列进程安全。返回true
}
bool exsitSafeList(Data *db)//判断是否存在安全序列
{
int i = 0;
for(i = 0;i pLength;i++)//设置逻辑尺的刻度值
{ db->ruler[i] = i;}
while(1)
//该循环将检测逻辑尺刻度值的全排列
{
if(checkList(db))
//找到一个安全序列,返回true
{ return true;}
db->clearProce();//将所有进程的currentAvail清零
if(!next_permutation(db->ruler,db->ruler+db->pLength))
//所有排列完毕后退出生成排列库函数的调用
{ return false;
}
}
return false;}
int findSafeList(Data *db, int i=0)//寻找安全序列
{
//请求值大于系统当前可用资源值,返回0
if(!db->ask.lower(db->available))
{ return 0;}
//请求值大于当前进程需求资源值,返回1
if(!db->ask.lower(db->p[i].claim_allocation))
{ return 1;}
Source s(db->p[i].allocation);//根据请求,分配资源值
db->available.sub(db->ask);
db->p[i].allocation.add(db->ask);
db->p[i].claim_allocation.sub(db->ask);
if(!exsitSafeList(db))//判断是否存在安全序列
{
db->available.add(db->ask);
//不存在安全序列,回滚,恢复分配前状态,并返回2
db->p[i].allocation.sub(db->ask);
db->p[i].claim_allocation.add(db->ask);
return 2;
}
db->ask.setSource(0,0,0);//找到安全序列,将请求资源置零,返回3
return 3;}
};3.功能模块设计
cla Data//封装所有数据
cla DataInit//封装初始化数据函数类 cla Display//封装显示方法
cla FindSafeList//寻找安全序列 struct Proce//进程属性构成
void main()//主函数
八、实验运行结果:
输入进程数,及相关资源数量分配
选择算法完成的操作:1 查看进程情况请求分配
2.1分配失败
2.2 分配成功
2.3 继续分配失败,退出
九、实验心得:
通过此次实验,我能够更加深入的理解银行家算法的执行过程,也懂得用银行家算法去防止发生死锁,有效地解决了资源利用率低的问题,保证了系统的安全性。
当然在实验过程中,我也遇到了一些困难,但是我通过及时请教同学,查询相关资料,及时解决了问题,但仍有不足之处,我将会在今后学习中更加努力。
附录:源代码(部分)
#include #include using namespace std;
cla Source //资源的基本构成以及功能 {
private: public: int R1;//定义三类类资源
int R2;int R3;
Source(int r1 = 0,int r2 = 0,int r3 = 0){ R1=r1;R2=r2;R3=r3;}
Source(Source& s){ R1=s.R1;R2=s.R2;R3=s.R3;}
void setSource(int r1 = 0,int r2 = 0,int r3 = 0)//设置各类资源
{ R1=r1;R2=r2;R3=r3;}
void add(Source s)//加法
{ R1=R1+s.R1;R2=R2+s.R2;R3=R3+s.R3;}
void sub(Source s)//减法
{ R1=R1-s.R1;R2=R2-s.R2;R3=R3-s.R3;}
bool lower(Source s)//比较
{
if(R1 > s.R1)return false;
if(R2 > s.R2)return false;
if(R3 > s.R3)return false;
return true;}
};
struct Proce//进程属性构成 { Source claim;//进程最大需求量
Source allocation;//进程占有量
Source claim_allocation;//进程需求量
Source currentAvail;//进程可获得量 };
cla Data//封装所有数据 { public: Proce *p;//进程指针
Source sum;//总资源量
Source available;//可获得量
Source ask;//请求量
int pLength;//进程个数
int * ruler;//逻辑尺
void clearProce()//进程currentAvail清零
{
for(int i=0;i
{ p[i].currentAvail.setSource(0, 0, 0);} } };
cla DataInit//封装初始化数据函数类 { private: public: DataInit()//构造函数
{ }
void initLength(Data *db)//设置进程个数
{
int n;
cout
cin>>n;
db->pLength = n;
db->p = new Proce[n];
if(!db->p)
{cout
db->ruler = new int[n];
if(!db->ruler){cout
void setAsk(Data *db)//设置请求资源量 { int r1,r2,r3;r1=0;r2=0;r3=0;
db->ask.setSource(r1,r2,r3);}
void initSum(Data *db)//设置总资源量
{ int r1,r2,r3;cout>r1>>r2>>r3;db->sum.setSource(r1,r2,r3);}
void initAvail(Data *db)//设置可获得量 { int r1,r2,r3;cout
cin>>r1>>r2>>r3;
db->available.setSource(r1,r2,r3);}
void initProce(Data *db)//设置各进程属性值 { int r1,r2,r3;coutpLength;i++)//设置进程p[i] 的 allocation {
cout
cin>>r1>>r2>>r3;
db->p[i].allocation.setSource(r1,r2,r3);
cout
cin>>r1>>r2>>r3;
db->p[i].claim.setSource(r1,r2,r3);
r1=db->p[i].claim.R1-db->p[i].claim.R1;//设置进程p[i] 的 claim_allocation
r2=db->p[i].claim.R2-db->p[i].claim.R2;
r3=db->p[i].claim.R3-db->p[i].claim.R3;
db->p[i].claim_allocation.setSource(r1, r2, r3);
} } };
cla Display//封装显示方法 { private: public: Display()//构造函数
{ }
void displaySource(Source s)//设置基本资源显示方式
{cout
displayAvailable(Source s)//显示可获得资源量
{displaySource(s);}
void displayProce(Proce *p,int length)//显示进程基本信息
{
for(int i=0;i
{
cout
displaySource(p[i].claim);
cout
displaySource(p[i].allocation);
cout
}
cout
void displaySafeList(Data *db)//显示安全序列
{
for(int i=0;ipLength;i++)
{
coutruler[i]
“;
displaySource(db->p[db->ruler[i]].currentAvail);
cout
”;
displaySource(db->p[db->ruler[i]].claim);
cout
“;
displaySource(db->p[db->ruler[i]].allocation);
cout
”;
displaySource(db->p[db->ruler[i]].claim_allocation);
cout
true“;
cout
} }
void displayAskResult(Data *db,int n)//显示请求资源结果
{
if(n==0)
{cout
if(n==1)
{cout
if(n==2)
{cout
if(n==3)
{
cout
for(int i=0;ipLength;i++)
{coutruler[i]
cout
char c='N';
cout
cin>>c;
if(c=='Y'||c=='y')
{
cout
currentavail
claim
allocation claim-allocation poiblen”;
displaySafeList(db);
}
return;
} } };
cla FindSafeList//寻找安全序列 { private: public: FindSafeList()//构造函数
{}
bool checkList(Data *db)//检查一个序列安全性
{
int i=0;//i用于循环
db->p[db->ruler[i]].currentAvail.add(db->available);//将当前系统可用资源量
赋给该序列的第一个进程
if(!db->p[db->ruler[i]].claim_allocation.lower(db->p[db->ruler[i]].currentAvail))//若当前进程currentAvail小于该进程需求量(claim-allocation),返回false
{return false;}
for(i=1;ipLength;i++)
{
//当前进程的可获得资源量currentAvail获得前一个进程的未释放资源前可获得资源量currentAvail
db->p[db->ruler[i]].currentAvail.add(db->p[db->ruler[i-1]].currentAvail);
//当前进程的可获得资源量currentAvail获得前一个进程的释放的资源量
db->p[db->ruler[i]].currentAvail.add(db->p[db->ruler[i-1]].allocation);
//若当前进程currentAvail小于该进程需求量(claim-allocation),返回false
if(!db->p[db->ruler[i]].claim_allocation.lower(db->p[db->ruler[i]].currentAvail))
{ return false;}
//若当前进程currentAvail大于该进程总资源量,返回false
if(!db->p[db->ruler[i]].currentAvail.lower(db->sum))
{ return false;}
}
return true;//该序列进程安全。返回true }
bool exsitSafeList(Data *db)//判断是否存在安全序列
{
int i = 0;
for(i = 0;i pLength;i++)//设置逻辑尺的刻度值
{ db->ruler[i] = i;}
while(1)
//该循环将检测逻辑尺刻度值的全排列
{
if(checkList(db))
//找到一个安全序列,返回true
{ return true;}
db->clearProce();//将所有进程的currentAvail清零
if(!next_permutation(db->ruler,db->ruler+db->pLength))
//所有排列完毕后退出生成排列库函数的调用
{ return false;
}
}
return false;}
int findSafeList(Data *db, int i=0)//寻找安全序列
{
//请求值大于系统当前可用资源值,返回0
if(!db->ask.lower(db->available))
{ return 0;}
//请求值大于当前进程需求资源值,返回1
if(!db->ask.lower(db->p[i].claim_allocation))
{ return 1;}
Source s(db->p[i].allocation);//根据请求,分配资源值
db->available.sub(db->ask);
db->p[i].allocation.add(db->ask);
db->p[i].claim_allocation.sub(db->ask);
if(!exsitSafeList(db))//判断是否存在安全序列
{
db->available.add(db->ask);
//不存在安全序列,回滚,恢复分配前状态,并返回2
db->p[i].allocation.sub(db->ask);
db->p[i].claim_allocation.add(db->ask);
return 2;
}
db->ask.setSource(0,0,0);//找到安全序列,将请求资源置零,返回3
return 3;}
};
void main(){ Data *db;db=new Data;if(!db){ cout
dataInit.initSum(db);//设置系统总资源量
dataInit.initAvail(db);//设置当前系统可获得资源量
dataInit.initProce(db);//设置t0时刻进程基本状态
Display display;FindSafeList findSafeList;int r1=0,r2=0,r3=0;int c;db->ask.setSource(r1,r2,r3);//设置请求资源为0,即无请求
c=findSafeList.findSafeList(db,0);//寻找安全序列,返回结果
if(c!=3){ cout
int choice=1;int pi;
while(choice){
cout
查看进程情况n请求分配资源n
0 退出n ";
cin>>choice;switch(choice){ case 1: {
}
case 2:
{
}
case 0:
{
default:
{
} } } coutavailable);coutp,db->pLength);break;cout>pi;cout>r1>>r2>>r3;db->ask.setSource(r1,r2,r3);c=findSafeList.findSafeList(db,pi);display.displayAskResult(db,c);cout
实验四死锁一、实验目的 当系统的总资源数m小于或等于所有进程对对资源的最大需求时,就可能产生 死锁。死锁会引起计算机系统的瘫痪。银行家算法是在实现资源分配时避免死锁......
操作系统课程设计(银行家算法的模拟实现)一、设计目的 1、进一步了解进程的并发执行。2、加强对进程死锁的理解。3、用银行家算法完成死锁检测。二、设计内容给出进程需求矩阵......
操作系统实验三:银行家算法的实现一、基本信息:a) 实验题目:银行家算法的实现 b) 完成人姓名:韩璐璐 c) 学号:71114115 d) 报告日期:2016.5.27二、实验目的通过实验,加深对多实例......
《计算机操作系统》课 程 设 计 报 告 题 目: 银行家算法班 级: XXXXXXXXXXXXXXXX 姓 名: XXM 学 号: XXXXXXXXXXXX 指导老师: XXXXXXXXXXXXXX 设计时间: XXXXXXXXXXXXXXX......
操作系统实验:银行家算法姓名:李天玮班级:软工1101 实验内容:在windows系统中实现银行家算法程序。学号:201126630117 实现银行家算法所用的数据结构:假设有5个进程3类资源,则有如......