参考博客:银行家算法详解(C语言)_Sparky*的博客-CSDN博客_银行家问题c语言
1. 效果展示
2. 程序流程图
3. 数据结构设计
/**定义数据结构*/
vector<vector<int>> Max;// 最大需求矩阵
vector<vector<int>> Allocation; // 已分配矩阵
vector<vector<int>> Need; // 需求矩阵
vector<int> Available; // 资源可用情况
vector<string> Name; // 资源名称
vector<int> Work; // 记录系统中当前各类可用资源的数目
vector<int> Request; // 系统对各类资源请求的数目
4. 功能函数设计
序号 | 函数 | 功能说明 |
1 | void print_cover(); | 打印程序封面 |
2 | void init_data(); | 初始化进程及资源数据 |
3 | void controller(); | 程序业务流程控制器 |
4 | void print_menu(); | 打印菜单命令 |
5 | bool security_detection(); | 安全性检测 |
6 | void display(); | 展示当前进程和资源信息 |
7 | int bank_getRequest(); | 接收用户手动分配资源信息 |
8 | bool bank_check(int id); | 检测数据是否符合银行家算法要求 |
9 | void try_allocate(int id); | 试分配资源 |
10 | void roll_back(int id); | 回滚操作 |
5. 代码实现
/// 银行家算法模拟实现
#include <bits/stdc++.h>
using namespace std;
/**定义数据结构*/
vector<vector<int>> Max;// 最大需求矩阵
vector<vector<int>> Allocation; // 已分配矩阵
vector<vector<int>> Need; // 需求矩阵
vector<int> Available; // 资源可用情况
vector<string> Name; // 资源名称
vector<int> Work; // 记录系统中当前各类可用资源的数目
vector<int> Request; // 系统对各类资源请求的数目
/**定义全局变量*/
int ProcessNum;// 系统中进程的数量
int ResourceNum;// 资源类型的数量
/**函数声明*/
void print_cover(); //打印系统封面
void init_data(); //初始化进程及资源数据
void controller(); //系统业务流程控制器
void print_menu(); //打印菜单命令
bool security_detection(); //安全性检测
void display(); //展示当前进程和资源信息
int bank_getRequest(); //接收用户手动分配资源信息
bool bank_check(int id); //检测数据是否符合银行家算法要求
void try_allocate(int id); //试分配资源
void roll_back(int id); //回滚操作
int main()
{
print_cover();
controller();
return 0;
}
void print_cover() {
printf("\t--------------------------\n");
printf("\t|| ||\n");
printf("\t|| 银行家算法模拟程序 ||\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t|| Seven ||\n");
printf("\t|| ||\n");
printf("\t--------------------------\n");
}
void print_menu() {
printf("\t-------------------------------------\n");
printf("\t|| ||\n");
printf("\t|| **手动进行资源请求** ||\n");
printf("\t|| 1. 查看资源矩阵及分配情况 ||\n");
printf("\t|| 2. 手动请求资源 ||\n");
printf("\t|| 0. 退出程序 ||\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t-------------------------------------\n");
}
void init_data() {
// 清空
Max.clear();
Allocation.clear();
// 输入资源信息
cout<<"请输入可用资源的种类数量:";
cin>>ResourceNum;
string temp_resourceName;
int temp_resourceNum;
for(int i=0; i<ResourceNum; i++)
{
cout<<"请输入第"<<i+1<<"个可用资源的名称: ";
cin>>temp_resourceName;
Name.push_back(temp_resourceName);
cout<<"请输入初始可用资源"<<Name[i]<<"的数量: ";
cin>>temp_resourceNum;
Available.push_back(temp_resourceNum);
}
cout<<endl;
// 输入进程信息
cout<<"请输入进程的数量:";
cin>>ProcessNum;
// 输入Max矩阵
cout<<"请输入进程的Max矩阵:"<<endl;
int temp_maxResourceNum;
vector<int> temp_Max;
for(int i=0; i<ProcessNum; i++){//遍历每一个进程
for(int j=0; j<ResourceNum ;j++){ //输入第i个进程中每种资源的数量
cin>>temp_maxResourceNum;
temp_Max.push_back(temp_maxResourceNum);
}
Max.push_back(temp_Max);
temp_Max.clear();
}
// 输入Allocation矩阵
cout<<"请输入进程的Allocation矩阵:"<<endl;
int temp_allocationNum;
int temp_needNum;
vector<int> temp_Allocation;
vector<int> temp_Need;
vector<int> temp_AllocationSum(ResourceNum); //记录每种资源的已分配数量
for(int i=0; i<ProcessNum; i++){//遍历每一个进程
for(int j=0; j<ResourceNum ;j++){ //遍历每一种资源
cin>>temp_allocationNum;
temp_Allocation.push_back(temp_allocationNum);
temp_needNum = Max[i][j] - temp_allocationNum;
temp_Need.push_back(temp_needNum);
temp_AllocationSum[j] += temp_allocationNum; //统计已经分配的资源量
}
Allocation.push_back(temp_Allocation);
temp_Allocation.clear();
Need.push_back(temp_Need);
temp_Need.clear();
}
for(int j=0; j<ResourceNum; j++)//更新可用资源数目Available
{
Available[j] = Available[j]-temp_AllocationSum[j];
}
}
void display() {
printf("\t--------------------\n");
printf("\t系统当前可用的资源矩阵Available:\n");
printf("\t\t");
for(int i=0; i<ResourceNum; i++) {
cout<<Name[i]<<" ";
}
printf("\n\t\t");
for(int i=0; i<ResourceNum; i++)
cout<<Available[i]<<" ";
printf("\n\t--------------------\n");
printf("\t系统当前资源分配情况如下: \n");
printf("\t Max Allocation Need\n");
printf("进程名 ");
for(int i=0; i<3; i++) {
for(int j=0; j<ResourceNum; j++) {
cout<<Name[j]<<" ";
}
}
cout<<endl;
for(int i=0; i<ProcessNum; i++){//打印进程
printf("P%d ",i);
for(int j=0; j<ResourceNum; j++){
printf("%d ",Max[i][j]);
}
for(int j=0; j<ResourceNum; j++){
printf("%d ",Allocation[i][j]);
}
for(int j=0; j<ResourceNum; j++){
printf("%d ",Need[i][j]);
}
cout<<endl;
}
}
int bank_getRequest() {
printf("请输入希望手动分配资源的进程的编号:");
int id;
cin>>id;
while(true)
{
if(id < 0 || id > ProcessNum-1)
printf("进程不存在!请重新输入\n请输入希望手动分配资源的进程的编号:");
else break;
cin>>id;
}
printf("请输入请求资源数(%d个):\n", ResourceNum);
int temp_requestNum;
for (int i = 0; i < ResourceNum; ++i) {
cin>>temp_requestNum;
Request.push_back(temp_requestNum);
}
cout<<"请求资源数录入完毕!"<<endl;
return id;
}
bool bank_check(int id) {
bool res = true;
// 判断银行家算法的前置条件是否成立:1. 申请是否大于需求,若大于则出错; 2. 申请是否大于当前可分配资源,若大于则出错
for (int i = 0; i < ResourceNum; ++i) {
if(Request[i]>Need[id][i]) {
printf("进程请求资源数大于所需资源数,无法分配!\n");
res=false;
break;
}
else if(Request[i]>Available[i]) {
printf("进程请求资源数大于可用资源数,无法分配!\n");
res=false;
break;
}
}
return res;
}
void try_allocate(int id) {
for (int i = 0; i < ResourceNum; ++i) {
Available[i] = Available[i] - Request[i];
Allocation[id][i] += Request[i];
Need[id][i] -= Request[i];
}
}
void roll_back(int id) {
for (int i = 0; i < ResourceNum; ++i) {
Available[i] = Available[i] + Request[i];
Allocation[id][i] -= Request[i];
Need[id][i] += Request[i];
}
}
void controller() {
// 保证输入初始数据后,系统是安全的
while(true) {
init_data();
display();
bool isSecure = security_detection();
if(isSecure) {
break;
} else {
cout<<"初始数据不合格,请重新输入!"<<endl;
}
}
// 用户选择自主选择手动分配资源或是退出程序
while (true) {
print_menu();
cout<<"请选择手动分配资源或是退出程序:";
// fflush(stdin);
int choice;
cin>>choice;
if(choice==1)
{
display();
}
else if(choice==2)
{
int id = bank_getRequest();
if(bank_check(id)){
printf("开始为进程%d进行资源试分配...\n", id);
try_allocate(id);
display();
if (security_detection()) {
cout<<"是否确认分配?(1.确认;2.取消)"<<endl;
int op;
while(true) {
cin>>op;
if(op==1) {
cout<<"已成功分配!"<<endl;
break;
} else if(op==2) {
roll_back(id);
cout<<"已取消分配!"<<endl;
break;
} else {
cout<<"请输入正确指令!(1.确认;2.取消)"<<endl;
}
}
}
}else{
cout<<"进程请求的资源数不合法,请重试!"<<endl;
}
} else if(choice==0) {
printf("已成功退出,欢迎下次使用银行家算法模拟程序!");
exit(0);
} else {
printf("不存在此指令,请重新输入!\n");
}
}
}
bool security_detection() {
//Finish:系统是否有足够的资源分配给进程,使之完成运行;开始时先令Finish[i]=false,当有足够资源分配给进程时,再令Finish[i]=true
vector<bool> Finish(ProcessNum, false);
// 在执行安全算法开始时,Work=Available
for (int i = 0; i < ResourceNum; ++i) {
Work.push_back(Available[i]);
}
// 开始检测
int finishedResource = 0; //统计一个进程中有多少种资源可以被满足
vector<int> SecuritySequence; // 保存进程在安全情况下的执行顺序
for (int i = 0; i < ProcessNum; ++i) {
//遍历完一个进程就将count置为0,对新的i号进程资源达标数进行计数
finishedResource = 0;
for (int j = 0; j < ResourceNum; ++j) {
// 如果进程没有执行且资源需求条件满足
if(!Finish[i] && Need[i][j]<=Work[j]) {
finishedResource++;
if(finishedResource==ResourceNum) {
Finish[i] = true; //标记进程可执行
// 回收Available空间
for (int k = 0; k < ResourceNum; ++k) {
Work[k] += Allocation[i][k];
}
SecuritySequence.push_back(i);
i = -1; // 从头开始遍历进程
}
}
}
}
// 判断系统是否安全
for (int i = 0; i < ProcessNum; ++i) {
if (!Finish[i]) {
cout<<"安全检测警告:系统不安全!"<<endl;
return false;
}
}
cout<<"安全检测成功:系统此时是安全的!"<<endl;
// 输出安全序列
for (int i = 0; i < SecuritySequence.size(); ++i) {
printf("P%d",SecuritySequence[i]);
if(i<SecuritySequence.size()-1) {
printf("-->");
}
}
cout<<endl;
return true;
}