银行家算法

我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。

#define _CRT_SECURE_NO_WARNINGS


#include<stdio.h>
#include<stdlib.h>
#include<string.h>


int time = 0; //执行轮数
int process = 0; //进程数
int reqprocess = 0; //请求资源的进程号
int source = 0; //资源数
int max[10][10]= { { 7,5,3 },{ 3,2,2 },{ 9,0,2 },{ 2,2,2 },{ 4,3,3 } }; //最大需求资源
int allocation[10][10]= { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} }; //已分配资源
int need[10][10] = {{7,4,3}, {1,2,2}, {6,0,0}, {0,1,1}, {4,3,1} }; //需求资源
int available[10]= { 3,3,2 }; //可用资源
int max_backup[10][10]= { { 7,5,3 },{ 3,2,2 },{ 9,0,2 },{ 2,2,2 },{ 4,3,3 } }; //备份
int allocation_backup[10][10]= { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} };
int need_backup[10][10] = {{7,4,3}, {1,2,2}, {6,0,0}, {0,1,1}, {4,3,1} };   
int available_backup[10]= { 3,3,2 };
int request[10][10]; //请求资源
int work[10]; //安全算法的可用资源
int order[10]; //安全序列
bool finish[10]; //运行完成


int main(); //函数声明
void initialize();
int confirm();


void automatic() //自动分配
{
process = 5;
source = 3;
printf("\n\n\t\t\t    自动分配完成!");
}


void ghost() //一键还原T0
{
int i,j;
process =5;
source =3;
for(i=0;i<process;i++)
{
for(j=0;j<source;j++)
{
max[i][j]=max_backup[i][j];
allocation[i][j]=allocation_backup[i][j];
need[i][j]=need_backup[i][j];
available[j]=available_backup[j];
}
}
time=0;
printf("\n\n\t\t\t    一键还原成功!");
}


void manual() //手动分配
{
int count = 1;
int i;
int j;
int choose;
while (count) {
printf("\n\n\t\t\t    ");
system("pause");
system("cls");
printf("\n\n\n");
printf("\n\n\t\t\t    请选择分配内容:");
printf("\n\n\t\t\t    1、进程种类个数");
printf("\n\n\t\t\t    2、资源种类个数");
printf("\n\n\t\t\t    3、最大需求资源");
printf("\n\n\t\t\t    4、已分配资源");
printf("\n\n\t\t\t    5、可用资源");
printf("\n\n\t\t\t    6、生成需求资源");
printf("\n\n\t\t\t    7、返回");
printf("\n\n\t\t\t    请选择:");
fflush(stdin);
scanf("%d", &choose);
switch (choose) {
case 1:
if (confirm() == 1)
{
printf("\n\n\t\t\t    请输入进程种类个数:");
fflush(stdin);
scanf("%d", &process);
printf("\n\t\t\t    进程个数已更改为%d\n", process);
break;
}
else
{
break;
}
case 2:
if (confirm() == 1)
{
printf("\n\n\t\t\t    请输入资源种类个数:");
fflush(stdin);
scanf("%d", &source);
printf("\n\t\t\t    资源个数已更改为%d\n", source);
break;
}
else
{
break;
}
case 3:
if (confirm() == 1)
{
if (process != 0 && source != 0)
{
for (i = 0; i < process; i++)
{
for (j = 0; j < source; j++)
{
printf("\n\n\t\t\t    P[%d]的%c类最大需求资源为:",i,j+'A');
fflush(stdin);
scanf("%d", &max[i][j]);
printf("\n\t\t\t    P[%d]的%c类最大需求资源已更改为%d\n",i,j+ 'A',max[i][j]);
}
}
printf("\n\n\t\t\t    最大需求资源更改已完成!");
break;
}
else
{
printf("\n\n\t\t\t    进程个数或资源个数尚未分配!");
break;
}
}
else
{
break;
}
case 4:
if (confirm() == 1)
{
if (process != 0 && source != 0)
{
for (i = 0; i < process; i++)
{
for (j = 0; j < source; j++)
{
printf("\n\n\t\t\t    P[%d]的%c类已分配资源为:", i, j+ 'A');
fflush(stdin);
scanf("%d", &allocation[i][j]);
printf("\n\t\t\t    P[%d]的%c类已分配资源已更改为%d\n", i, j+ 'A', allocation[i][j]);
}
}
printf("\n\n\t\t\t    已分配资源更改已完成!");
break;
}
else
{
printf("\n\n\t\t\t    进程个数或资源个数尚未分配!");
break;
}
}
else
{
break;
}
case 5:
if (confirm() == 1)
{
if (source != 0)
{
for (i = 0; i < source; i++)
{
printf("\n\n\t\t\t    %c类可用资源为:", i+ 'A');
fflush(stdin);
scanf("%d", &available[i]);
printf("\n\t\t\t    %c类可用资源已更改为%d\n", i+ 'A', available[i]);
}
printf("\n\n\t\t\t    可用资源更改已完成!");
break;
}
else
{
printf("\n\n\t\t\t    资源个数尚未分配!");
break;
}
}
else
{
break;
}
case 6:
if (confirm() == 1)
{
// if (max[0][0] != NULL && allocation[0][0] != NULL)
// {
for (i = 0; i < process; i++)
{
for (j = 0; j < source; j++)
{
need[i][j] = max[i][j] - allocation[i][j];
printf("\n\n\t\t\t    P[%d]的%c类需求资源已更改为%d",i, j + 'A', need[i][j]);
}
}
printf("\n\n\t\t\t    需求资源更改已完成!");
break;
// }
// else
// {
// printf("\n\n\t\t\t    最大需求资源或已分配资源尚未分配!");
// break;
// }
}
else
{
break;
}
case 7:
count = 0;
break;
default:
printf("\n\n\t\t\t输入错误!请重新输入!\n");
break;
}
}
}


void initialize() //初始化资源分配
{
int count = 1;
int choose;
while (count) {
printf("\n\n\t\t\t    \n\n\t\t\t    ");
system("pause");
system("cls");
printf("\n\n\n");
printf("\n\n\t\t\t    请选择资源分配模式:");
printf("\n\n\t\t\t    1、自动分配");
printf("\n\n\t\t\t    2、手动分配");
printf("\n\n\t\t\t    3、返回");
printf("\n\n\t\t\t    请选择:");
fflush(stdin);
scanf("%d", &choose);
switch (choose) {
case 1:
automatic();
break;
case 2:
manual();
break;
case 3:
count = 0;
break;
default:
printf("\n\n\t\t\t    输入错误!请重新输入!");
break;
}
}
}


bool notin(int *o,int index) //判断数字是否在数组中(没有用)
{
int i;
for (i = 0; i < process; i++)
{
if (index == o[i])
{
return false;
}
}
return true;
}


int securityexamine() //安全性检测
{
int i,j,k; //计数器
int h=0; //顺序计数器
int number; //true个数计数器
int count=1;
for (i = 0; i < source; i++)
{
work[i] = available[i];
}
while (count) {
count = 0;
for (i = 0; i < process; i++)
{
number = 0;
for (j = 0; j < source; j++)
{
need[i][j] <= work[j] ? number++ : number += 0;
if (finish[i] == false && number == source)
{
finish[i] = true;
count = 1;
for (k = 0; k < source; k++)
{
work[k] += allocation[i][k];
}
order[h++]=i;
i=-1;
}
}
// if ( finish[i] && h<source && notin(order,i))
// {
// order[h++] = i;
// }
}
}
for (i = 0; i < process; i++)
{
if (finish[i] == false)
{
printf("\n\n\t\t\t    此时刻[T%d]为不安全状态,中止请求!",time);
for (j = 0; j < source; j++)
{
available[j] = available[j] + request[reqprocess][j];
allocation[reqprocess][j] = allocation[reqprocess][j] - request[reqprocess][j];
need[reqprocess][j] = need[reqprocess][j] + request[reqprocess][j];
}
return 0;
}
}
printf("\n\n\t\t\t    此时刻[T%d]为安全状态,可分配!",time);
return 1;
}


void bankeralgorithm() //银行家算法
{
int count = 1;
int i;
while (count)
{
printf("\n\n\t\t\t    ");
system("pause");
system("cls");
if (process == 0 || source==0)
{
printf("\n\n\t\t\t    进程或资源尚未初始化!");
break;
}
printf("\n\n\t\t\t    为几号进程请求资源:P[n]");
printf("\n\n\t\t\t                       n = ");
fflush(stdin);
scanf("%d", &reqprocess);
if (reqprocess >= 0 && reqprocess < process)
{
printf("\n\n\t\t\t     P [ %d ]的请求资源类型:", reqprocess);
for (i = 0; i < source; i++)
{
printf("%c ",i+'A');
}
printf("\n\n\t\t\t    请求资源数(以空格隔开):");
for (i = 0; i < source; i++)
{
fflush(stdin);
scanf("%d", &request[reqprocess][i]);
if (request[reqprocess][i] > need[reqprocess][i])
{
printf("\n\n\t\t\t    %c类请求资源数超过需求资源!未输入!",i+'A');
}
if (request[reqprocess][i] > available[i])
{
printf("\n\n\t\t\t    %c类可用资源不足!未输入!", i + 'A');
}
available[i] = available[i] - request[reqprocess][i];
allocation[reqprocess][i] = allocation[reqprocess][i] + request[reqprocess][i];
need[reqprocess][i] = need[reqprocess][i] - request[reqprocess][i];
}
}
else
{
printf("\n\n\t\t\t    进程不在范围内,未输入!");
continue;
}
securityexamine();
time++;
break;
}
}


void mutiplyshow()
{
int i,j;
printf("\n\n\t\t\t    \n\n\t\t\t    ");
system("pause");
system("cls");
if (process == 0 || source == 0)
{
printf("\n\n\t\t\t    进程或资源尚未初始化!");
exit;
}
printf("\n\n\t    最大需求"); //第一行开始
for(i=0;i<source;i++)
{
printf(" ");
}
printf(" 已分配");
for(i=0;i<source;i++)
{
printf(" ");
}
printf("  需求");
for(i=0;i<source;i++)
{
printf(" ");
}
printf("  可用");
for(i=0;i<source;i++)
{
printf(" ");
} //第一行结束


printf("\n\n      "); //第二行开始
printf("进程:");
for(i=0;i<4;i++)

printf("  ");
for(j=0;j<source;j++)
{
printf("%c ",j+'A');
}
printf("  ");
} //第二行结束


for(i=0;i<process;i++)
{
printf("\n      P[%d]:",i);
printf("  ");
for(j=0;j<source;j++)
{
printf("%d ",max[i][j]);
}
printf("    ");
for(j=0;j<source;j++)
{
printf("%d ",allocation[i][j]);
}
printf("    ");
for(j=0;j<source;j++)
{
printf("%d ",need[i][j]);
}
printf("    ");
for(j=0;j<source;j++)
{
if(i!=0)
{
continue;
}
else
{
printf("%d ",available[j]);
}
}
}
}


void singleshow() //单个资源输出
{
int i;
int j;
int count = 1;
int choose;
while (count) {
printf("\n\n\t\t\t    \n\n\t\t\t    ");
system("pause");
system("cls");
if (process == 0 || source == 0)
{
printf("\n\n\t\t\t    进程或资源尚未初始化!");
break;
}
printf("\n\n\n");
printf("\n\n\t\t\t    请选择查询内容:");
printf("\n\n\t\t\t    1、最大需求资源");
printf("\n\n\t\t\t    2、已分配资源");
printf("\n\n\t\t\t    3、需求资源");
printf("\n\n\t\t\t    4、可用资源");
printf("\n\n\t\t\t    5、返回");
printf("\n\n\t\t\t    请选择:");
fflush(stdin);
scanf("%d", &choose);
switch (choose) {
case 1:
printf("\n\n\t\t\t     资源类型:");
for (i = 0; i < source; i++)
{
printf("%c ", i + 'A');
}
for (i = 0; i < process; i++)
{
printf("\n\n\t\t\t     P [ %d ] :", i);
for (j = 0; j < source; j++)
{
printf("%d ", max[i][j]);
}
}
break;
case 2:
printf("\n\n\t\t\t     资源类型:");
for (i = 0; i < source; i++)
{
printf("%c ", i + 'A');
}
for (i = 0; i < process; i++)
{
printf("\n\n\t\t\t     P [ %d ] :", i);
for (j = 0; j < source; j++)
{
printf("%d ", allocation[i][j]);
}
}
break;
case 3:
printf("\n\n\t\t\t     资源类型:");
for (i = 0; i < source; i++)
{
printf("%c ", i + 'A');
}
for (i = 0; i < process; i++)
{
printf("\n\n\t\t\t     P [ %d ] :", i);
for (j = 0; j < source; j++)
{
printf("%d ", need[i][j]);
}
}
break;
case 4:
printf("\n\n\t\t\t     资源类型:");
for (i = 0; i < source; i++)
{
printf("%c ", i + 'A');
}
printf("\n\n\t\t\t     可用资源:");
for (i = 0; i < source; i++)
{
printf("%d ", available[i]);
}
break;
case 5:
count = 0;
break;
default:
printf("\n\n\t\t\t    输入错误!请重新输入!");
break;
}
}
}


void show() //输出菜单
{
int count = 1;
int choose;
while (count) {
printf("\n\n\t\t\t    \n\n\t\t\t    ");
system("pause");
system("cls");
printf("\n\n\n");
printf("\n\n\t\t\t    请选择显示模式:");
printf("\n\n\t\t\t    1、整体资源显示");
printf("\n\n\t\t\t    2、单个资源显示");
printf("\n\n\t\t\t    3、返回");
printf("\n\n\t\t\t    请选择:");
fflush(stdin);
scanf("%d", &choose);
switch (choose) {
case 1:
mutiplyshow();
break;
case 2:
singleshow();
break;
case 3:
count = 0;
break;
default:
printf("\n\n\t\t\t    输入错误!请重新输入!");
break;
}
}
}


void output()
{
int i;
securityexamine();
printf("\n\n\t\t\t    安全序列为:");
for (i = 0; i < process; i++)
{
printf("P[%d] ",order[i]);
}
}


void menu() //菜单
{
printf("\n\n\t\t\t    ");
system("pause");
system("cls");
printf("\n\n\t\t\t\t<银行家算法>\n");
printf("\n\n\t\t\t    1、初始化T0时刻资源分配状态");
printf("\n\n\t\t\t    2、显示当前时刻(T%d)资源分配状态", time);
printf("\n\n\t\t\t    3、显示一个安全序列");
printf("\n\n\t\t\t    4、进程请求资源");
printf("\n\n\t\t\t    5、一键还原T0时刻资源分配状态");
printf("\n\n\t\t\t    6、退出系统");
printf("\n\n\t\t\t    请选择:");
}


int confirm() //再确认
{
int count = 1;
char str[10];
while (count) {
printf("\n\n\t\t\t    此操作不可返回,确认执行此操作吗?");
printf("\n\n\t\t\t                             yes/no?");
printf("\n\n\t\t\t                             ");
fflush(stdin);
scanf("%s", str);
if (strcmp(str, "yes") == 0)
{
system("cls");
return 1;
}
else if (strcmp(str, "no") == 0)
{
return 0;
}
else
{
printf("\n\n\t\t\t    输入错误!请重新输入!");
}
}
return 0;
}


int main()
{
int count = 1;
int choose;
while (count) {
menu();
fflush(stdin);
scanf("%d", &choose);
switch (choose) {
case 1:
initialize();
break;
case 2:
show();
break;
case 3:
output();
break;
case 4:
bankeralgorithm();
break;
case 5:
ghost();
break;
case 6:
if (confirm() == 1)
{
return 0;
}
break;
default:
printf("\n\n\t\t\t    输入错误!请重新输入!");
break;
}
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值