一、实验目的
银行家算法是避免死锁的一种重要方法,要求编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
二、实验要求
1.设计进程对各类资源最大申请表示及初值确定。
2.设定系统提供资源初始状况。
3.设定每次某个进程对各类资源的申请表示。
4.编制程序,依据银行家算法,决定其申请是否得到满足。
三、实验原理
1.数据结构
假设有M个进程N类资源,则有如下数据结构:
MAX[MN] M个进程对N类资源的最大需求量
AVAILABLE[N] 系统可用资源数
ALLOCATION[MN] M个进程已经得到N类资源的资源量
NEED[M*N] M个进程还需要N类资源的资源量
2.银行家算法
设进程I提出请求Request[N],则银行家算法按如下规则进行判断。
(1)如果Request[N]<=NEED[I,N],则转(2);否则,出错。
(2)如果Request[N]<=AVAILABLE,则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE=AVAILABLE-REQUEST
ALLOCATION=ALLOCATION+REQUEST
NEED=NEED-REQUEST
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
3.安全性检查
(1)设置两个工作向量WORK=AVAILABLE;FINISH[M]=FALSE
(2)从进程集合中找到一个满足下述条件的进程,
FINISH[i]=FALSE
NEED<=WORK
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
WORK=WORK+ALLOCATION
FINISH=TRUE
GO TO 2
(4)如所有的进程Finish[M]=true,则表示安全;否则系统不安全。
实现代码如下:
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#define M 5//进程数
#define N 3//资源数
using namespace std;
//M个进程对N类资源最大资源需求量
int MAX[M][N] = { {7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3} };
//系统可用资源数
int AVAILABLE[N] = { 3,3,2 };
//M个进程已分配到的N类数量
int ALLOCATION[M][N] = { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} };
//M个进程还需要N类资源的资源量
int NEED[M][N] = { {7,4,3},{1,2,2},{6,0,0},{2,1,1},{4,3,1} };
//可请求的N类资源数
int Request[N] = { 1,0,2 };
//打印当前资源分配情况
void show()
{
int i, j;
cout << endl;
cout<<"----系统可用资源向量:"<<endl;
cout<<"----Available----" << endl;
cout<<"资源类别:A B C" << endl;
cout<<"资源数目:" << endl;
for (j = 0; j < N; j++)
{
cout<<AVAILABLE[j]<<" ";
}
cout<<endl<<endl;
cout<<"-----各进程还需要的资源量:" << endl;
cout << "-----Need-----" << endl;
cout << "资源类别:A B C" << endl;
for (i = 0; i < M; i++)
{
cout << i << "号进程:" << endl;
for (j = 0; j < N; j++)
{
cout << NEED[i][j]<<" ";
}
cout << endl;
}
cout << endl;
cout<<"---各进程已经得到的资源量:" << endl;
cout << "---Allocation---" << endl;
cout << "资源类别:A B C" << endl;
for (i = 0; i < M; i++)
{
cout << i << "号进程:" << endl;
for (j = 0; j < N; j++)
{
cout << ALLOCATION[i][j]<<" ";
}cout << endl;
}
cout << endl;
}
//尝试请求资源
void request(int k)
{
int j;
for (j = 0; j < N; j++)
{
AVAILABLE[j] = AVAILABLE[j] - Request[j];
ALLOCATION[k][j] = ALLOCATION[k][j] + Request[j];
NEED[k][j] = NEED[k][j] - Request[j];
}
}
//重置资源
void reset(int k)
{
int j;
for (j = 0; j < N; j++)
{
AVAILABLE[j] = AVAILABLE[j] + Request[j];
ALLOCATION[k][j] = ALLOCATION[k][j] - Request[j];
NEED[k][j] = NEED[k][j] + Request[j];
}
}
//安全检查函数
int check()//在假定分配资源的情况下检查系统的安全性
{
int WORK[N], temp[M];//工作向量work[],temp[]用来记录进程安全执行的顺序
bool FINISH[M];
int i, j, m, k = 0, count;
for (i = 0; i < M; i++)
FINISH[i] = false;
for (j = 0; j < N; j++)
WORK[j] = AVAILABLE[j];//把可利用资源数赋给WORK[]
for (i = 0; i < M; i++)//循环进程
{
count = 0;
for (j = 0; j < N; j++)//循环资源种类
{
if (FINISH[i] == false && NEED[i][j] <= WORK[j])
count++;
if (count == N)//当进程各类资源都满足NEED<=WORK时
{
for (m = 0; m < N; m++)
{
WORK[m] = WORK[m] + ALLOCATION[i][m];
}
FINISH[i] = true;
temp[k] = i;//记录下满足条件的进程
k++;i = -1;
}
}
}
for (i = 0; i < M; i++)
{
if (FINISH[i] == false)
{
cout<<"系统不安全!进程"<<i<<"分配失败本次申请失败"<<endl;
return 1;
}
cout << endl << "系统安全,进程"<<i<<"分配成功。";
}
for (i = 0; i < M; i++)//打印安全系统的进程调用顺序
{
cout<<" 本次安全序列:";
cout<<temp[i];
}
cout << endl;
return 0;
}
void main()
{
int i = 0, j = 0,sum=0;
int r;
bool flag=false;
do {
cout << "是否请求资源?是请输入1,否请输入0"<<endl;
cin >> r;
if (r)
{
cout << "请输入申请进程号(0-" << M - 1 << "):" << endl;
cin >> i;
cout << "申请的资源数:" << endl;
cout << "类别:A B C" << endl;
for (j = 0; j < N; j++)
{
cout << Request[j]<<" ";
if (Request[j] > NEED[i][j])
{
cout <<endl<< i << "号进程申请的资源数大于进程需要资源数!申请失败!请重新申请!" << endl;
flag = true;
}
else if (Request[j] > AVAILABLE[j])
{
cout << endl << i << "号进程申请的资源数大于系统可用资源数,申请失败!请重新申请!" << endl;
flag = true;
}
else { flag = false; sum++; }
}
}else { break; }
if(sum==3){ request(i); }
} while (flag);
if (check()&&r==1)//申请资源并且申请资源失败不是安全序列
{
reset(i);
show();
}
else { show(); }
}
控制台输入实现如下:
主要思路:
首先要理解算法
初始化阶段:首先要对各个进程进行分配资源MAX[],ALLOCTION[],NEED[],以及预设的Request[] (如需输入设置 可在main函数中添加给request的赋值语句)
主函数:1.进入main函数判断是否需要请求资源,①不需要则直接进行运算,②若需要则判断请求资源是否合法,③不合法则重新请求若合法④合法则执行check()函数⑤输出show()函数查看结果