大家好,又见面了,我是你们的朋友全栈君。
主要参考链接:
https://blog.csdn.net/houchaoqun_xmu/article/details/55540792
https://liuyanzhao.com/2932.html(这个是额外贴出可以参考的连接。本文的主要参考链接依旧是第一条)
[声明]本文为转载是因为代码大多数都是网上copy的,然后自己也只是微调加实现过,个人认为不可以当原创。代码全部都贴上来了,txt文档的格式也贴了,也实现过,如果期间遇到困难,希望你们再去找其他的资料,问我的话我未必能答上来。
操作系统系列文章:
主要的数据结构
#define MaxNumber 20
static int n;//当前进程个数
static int m;//当前资源个数
static int Available[MaxNumber];
static int Max[MaxNumber][MaxNumber];
static int Allocation[MaxNumber][MaxNumber];
static int Need[MaxNumber][MaxNumber];
static int Request[MaxNumber];
static int SafeOrder[MaxNumber];
static bool Finish[MaxNumber];
static char sourceName[] = {'A','B','C','D','E','F','G','H','I','J','K'}; //资源名称
用到的函数
void input();//在文件中录入数据
bool isSystemSafe();//安全性算法
void bankerAlgorithm();//银行家算法
void display();//录入数据后的第一次输入
void display_later(); //之后的每一次输出
void display_array(int a[MaxNumber][MaxNumber],int n,int m);//专门负责二维数组a[][]的第n行的输出
void display_array_one(int a[MaxNumber],int m);//专门负责一维数组a[]的第n行的输出
核心算法
银行家算法函数
void bankerAlgorithm()
{
int chooseProcess;
char isContinue;
while(true)
{
//设置两个布尔变量:判别请求向量是等待还是系统已经不再分配新的资源
bool isRequestNeedOK = true;
bool isRequestAvailableOK = true;
int isAll_0=1;
int isSafe=1;
printf("\n请输入要申请资源的进程号(注意:P0进程为0)\n");
printf("chooseProcess=");
scanf("%d",&chooseProcess);
printf("请输入进程所请求的各类资源的数量:(A B C):");
for(int i=0;i<m;i++){
scanf("%d",&Request[i]);
}
//输入错误判断
for (int i=0;i<m;i++)
{
if (Request[i]>Need[chooseProcess][i])
{
printf("**************************当前运行结果*****************************\n");
printf("您输入的请求进程所对应的资源数量超过最大需求量,请重新输入!\n");
isRequestNeedOK = false;
break;
}
if (Request[i]>Available[i])
{
printf("**************************当前运行结果*****************************\n");
printf("您输入的请求进程的资源数量超过系统所供给的最大资源数量,必须等待。请重新输入!\n");
isRequestAvailableOK = false;
break;
}
}
if(isRequestNeedOK && isRequestAvailableOK) //当输入满足最基本的要求(上面两条)
{
for (int j = 0;j<m;j++)
{
Available[j] -= Request[j];
Allocation[chooseProcess][j] += Request[j];
Need[chooseProcess][j] -= Request[j];
}
printf("**************************当前运行结果*****************************\n");
if (!isSystemSafe()) //如何不满足系统安全性算法,将本次试探作废,恢复到原来的值
{
isSafe=0;
for (int j = 0;j<m;j++)
{
Available[j] +=Request[j];
Allocation[chooseProcess][j] -= Request[j];
Need[chooseProcess][j] += Request[j];
}
printf("****************系统将进入不安全状态,故不分配资源******************\n");//系统将进入不安全状态,故不分配资源
}
//资源回收
for(int j=0;j<m;j++)
{
if(Need[chooseProcess][j]!=0)
{
isAll_0=0; //说明不是全0,即进程还未满足
break;
}
}
if(isAll_0==1)
{
for(int j=0;j<m;j++)
{
Available[j] += Allocation[chooseProcess][j];
}
}
//是否继续输入
printf("是否继续输入请求变量request进行测试,是(Y),否(N)\n");
printf("isContinue =");
scanf(" %c",&isContinue);
if (isContinue=='Y'|| isContinue=='y')
{
if(isAll_0==0 && isSafe)//isAll_0为0,即不能把占有的交出来,即进程还没完成
printf("\nP(%d)成功分配后的资源分配表如下:\n",chooseProcess);
else if(isAll_0 && isSafe)
printf("\nP(%d)成功完成任务,归还所占有的资源。资源分配表如下:\n",chooseProcess);
else
printf("\n资源分配表如下:\n");
display_later();
continue;
}
else if (isContinue=='N' || isContinue=='n')
{
printf("******************************程序结束*****************************\n");
break;
}
}
}
}
安全性检查函数
bool isSystemSafe()
{
int work[MaxNumber];
for (int i=0;i<m;i++) //m是资源个数A,B,C
{
work[i] = Available[i];
}
for (int i=0;i<n;i++) //n是进程个数
{
Finish[i] = false;
SafeOrder[i] = -1; //初始化安全序列
}
int FinishNumber = 0;
int isSafe;
int i =0,j;
while(i<n)
{
isSafe = 0;
for(j = 0;j<m;j++)
{
if (Finish[i]==false && Need[i][j]<=work[j])
{
isSafe++;
}
else
break;
}
if (isSafe == m) //当且仅当进程对应的所有资源的数量都满足的时候才成立
{
Finish[i] = true;
SafeOrder[FinishNumber] = i;
FinishNumber++;
for (j = 0;j<m;j++)
{
work[j] += Allocation[i][j];
}
i=0; //找到满足条件的进程后,从头开始再进行寻找
}
else
i++;
if (FinishNumber==n)
{
printf("**************************系统为安全状态*****************************\n");
printf("对应的安全序列为:");
for(int i=0;i<n-1;i++)
{
printf("P%d--->",SafeOrder[i]);
}
printf("P%d\n",SafeOrder[n-1]);
return true;
}
}
return false;
}
主函数
int main()
{
input();
if(isSystemSafe()) //先判断输入的数据有没有安全序列;
{
bankerAlgorithm();
}
else printf("输入的资源分配表不存在安全序列,请重新输入");
system("pause");
return 0;
}
测试数据的输入
源代码
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define MaxNumber 20
static int n;//当前进程个数
static int m;//当前资源个数
static int Available[MaxNumber];
static int Max[MaxNumber][MaxNumber];
static int Allocation[MaxNumber][MaxNumber];
static int Need[MaxNumber][MaxNumber];
static int Request[MaxNumber];
static int SafeOrder[MaxNumber];
static bool Finish[MaxNumber];
static char sourceName[] = {'A','B','C','D','E','F','G','H','I','J','K'}; //资源名称
void input();//在文件中录入数据
bool isSystemSafe();//安全性算法
void bankerAlgorithm();//银行家算法
void display();//录入数据后的第一次输入
void display_later(); //之后的每一次输出
void display_array(int a[MaxNumber][MaxNumber],int n,int m);//专门负责二维数组a[][]的第n行的输出
void display_array_one(int a[MaxNumber],int m);//专门负责一维数组a[]的第n行的输出
int main()
{
input();
if(isSystemSafe()) //先判断输入的数据有没有安全序列;
{
bankerAlgorithm();
}
else printf("输入的资源分配表不存在安全序列,请重新输入");
system("pause");
return 0;
}
void input()
{
FILE *fp;
fp=fopen("银行家数据.txt","r");
if(fp==NULL){
exit(EXIT_FAILURE);
}
//读取数据
fscanf(fp,"%d",&n);//当前进程个数
fscanf(fp,"%d",&m);//当前资源个数
for (int i=0;i<m;i++)
{
fscanf(fp,"%d",&Available[i]);
}
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
fscanf(fp,"%d",&Allocation[i][j]);
}
}
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
fscanf(fp,"%d",&Need[i][j]);
}
}
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
Max[i][j] = Need[i][j] + Allocation[i][j];
}
}
printf("*****************************程序开始*******************************\n");
//测试代码
// for (int i=0;i<n;i++)
// {
// for (int j=0;j<m;j++)
// {
// if(j%m==0)printf("\n");
// printf("%d ",Max[i][j]);
//
// }
// }
display();
}
void display_array(int a[MaxNumber][MaxNumber],int n,int m){//输出数组第n行的数据
int i;
for(i=0;i<m;i++){
printf(" %d ",a[n][i]);
}
printf(" ");
}
void display_array_one(int a[MaxNumber],int m){
int i;
for(i=0;i<m;i++){
printf(" %d ",a[i]);
}
}
void display(){
// char processName[] = {'1','2','3','4','5','6'};
printf("----------------------------------------------------------------------\n");
printf("当前进程个数为 n = %d\n",n);
printf("当前资源个数为 m = %d\n",m);
printf("系统可利用资源数情况如下:\n");
for (int i=0;i<m;i++)
{
printf(" %c ",sourceName[i]);
}
printf("\n");
for (int i=0;i<m;i++){
printf(" %d ",Available[i]);
}
printf("\n");
printf("----------------------------------------------------------------------\n");
if(m==3)
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m=3,3个资源
else if(m==4)
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m=4,4个资源
else
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m>=5,5个资源
printf(" ");
for(int i=1;i<=4;i++)
{
printf(" ");
for(int j=0;j<m;j++)
{
printf(" %c ",sourceName[j]);
}
}
printf("\n");
for(int i=0;i<n;i++)
{
printf(" P%d ",i);
printf(" ");
if(i==0)
{
display_array(Max,i,m);
display_array(Allocation,i,m);
display_array(Need,i,m);
display_array_one(Available,m);
}
else
{
display_array(Max,i,m);
display_array(Allocation,i,m);
display_array(Need,i,m);
}
printf("\n");
}
}
void display_later() {
printf("----------------------------------------------------------------------\n");
if(m==3)
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m=3,3个资源
else if(m==4)
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m=4,4个资源
else
printf("processName Max[][] Allocation[][] Need[][] Available[]\n");//m=5,5个资源
printf(" ");
for(int i=1;i<=4;i++)
{
printf(" ");
for(int j=0;j<m;j++)
{
printf(" %c ",sourceName[j]);
}
}
printf("\n");
for(int i=0;i<n;i++)
{
printf(" P%d ",i);
printf(" ");
if(i==0)
{
display_array(Max,i,m);
display_array(Allocation,i,m);
display_array(Need,i,m);
display_array_one(Available,m);
}
else
{
display_array(Max,i,m);
display_array(Allocation,i,m);
display_array(Need,i,m);
}
printf("\n");
}
}
void bankerAlgorithm()
{
int chooseProcess;
char isContinue;
while(true)
{
//设置两个布尔变量:判别请求向量是等待还是系统已经不再分配新的资源
bool isRequestNeedOK = true;
bool isRequestAvailableOK = true;
int isAll_0=1;
int isSafe=1;
printf("\n请输入要申请资源的进程号(注意:P0进程为0)\n");
printf("chooseProcess=");
scanf("%d",&chooseProcess);
printf("请输入进程所请求的各类资源的数量:(A B C):");
for(int i=0;i<m;i++){
scanf("%d",&Request[i]);
}
//输入错误判断
for (int i=0;i<m;i++)
{
if (Request[i]>Need[chooseProcess][i])
{
printf("**************************当前运行结果*****************************\n");
printf("您输入的请求进程所对应的资源数量超过最大需求量,请重新输入!\n");
isRequestNeedOK = false;
break;
}
if (Request[i]>Available[i])
{
printf("**************************当前运行结果*****************************\n");
printf("您输入的请求进程的资源数量超过系统所供给的最大资源数量,必须等待。请重新输入!\n");
isRequestAvailableOK = false;
break;
}
}
if(isRequestNeedOK && isRequestAvailableOK) //当输入满足最基本的要求(上面两条)
{
for (int j = 0;j<m;j++)
{
Available[j] -= Request[j];
Allocation[chooseProcess][j] += Request[j];
Need[chooseProcess][j] -= Request[j];
}
printf("**************************当前运行结果*****************************\n");
if (!isSystemSafe()) //如何不满足系统安全性算法,将本次试探作废,恢复到原来的值
{
isSafe=0;
for (int j = 0;j<m;j++)
{
Available[j] +=Request[j];
Allocation[chooseProcess][j] -= Request[j];
Need[chooseProcess][j] += Request[j];
}
printf("****************系统将进入不安全状态,故不分配资源******************\n");//系统将进入不安全状态,故不分配资源
}
//资源回收
for(int j=0;j<m;j++)
{
if(Need[chooseProcess][j]!=0)
{
isAll_0=0; //说明不是全0,即进程还未满足
break;
}
}
if(isAll_0==1)
{
for(int j=0;j<m;j++)
{
Available[j] += Allocation[chooseProcess][j];
}
}
//是否继续输入
printf("是否继续输入请求变量request进行测试,是(Y),否(N)\n");
printf("isContinue =");
scanf(" %c",&isContinue);
if (isContinue=='Y'|| isContinue=='y')
{
if(isAll_0==0 && isSafe)//isAll_0为0,即不能把占有的交出来,即进程还没完成
printf("\nP(%d)成功分配后的资源分配表如下:\n",chooseProcess);
else if(isAll_0 && isSafe)
printf("\nP(%d)成功完成任务,归还所占有的资源。资源分配表如下:\n",chooseProcess);
else
printf("\n资源分配表如下:\n");
display_later();
continue;
}
else if (isContinue=='N' || isContinue=='n')
{
printf("******************************程序结束*****************************\n");
break;
}
}
}
}
bool isSystemSafe()
{
int work[MaxNumber];
for (int i=0;i<m;i++) //m是资源个数A,B,C
{
work[i] = Available[i];
}
for (int i=0;i<n;i++) //n是进程个数
{
Finish[i] = false;
SafeOrder[i] = -1; //初始化安全序列
}
int FinishNumber = 0;
int isSafe;
int i =0,j;
while(i<n)
{
isSafe = 0;
for(j = 0;j<m;j++)
{
if (Finish[i]==false && Need[i][j]<=work[j])
{
isSafe++;
}
else
break;
}
if (isSafe == m) //当且仅当进程对应的所有资源的数量都满足的时候才成立
{
Finish[i] = true;
SafeOrder[FinishNumber] = i;
FinishNumber++;
for (j = 0;j<m;j++)
{
work[j] += Allocation[i][j];
}
i=0; //找到满足条件的进程后,从头开始再进行寻找
}
else
i++;
if (FinishNumber==n)
{
printf("**************************系统为安全状态*****************************\n");
printf("对应的安全序列为:");
for(int i=0;i<n-1;i++)
{
printf("P%d--->",SafeOrder[i]);
}
printf("P%d\n",SafeOrder[n-1]);
return true;
}
}
return false;
}
实验截图
对P1请求1 0 2:没有超出最大值,并检测到有安全序列,因此允许分配。此时,Allocation,Need,Available都有相应变化。
(注意!只有当输入了Y或y才会看到成功分配后的资源分配表)
继续对P1请求 0 2 0:没有超出最大值,并检测到有安全序列,因此允许分配。而且,P1成功完成任务,将原先占有的资源归还给系统。(资源回收)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141888.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...