/*----银行家算法-----*/
#include<stdio.h>
#include<iostream.h>
#include<windows.h>
#include<string.h>
#include <malloc.h>
#include <process.h>
#include<stdlib.h>
/*---宏定义部分-----*/
#define M 3
#define N 5
#define NULL 0
/*----数据结构部分---*/
typedef struct MYPCB{
char pname[5];
char flags[10];
int Allocation[M];
int Max[M];
int Need[M];
}PCB;
/*----函数声明部分--*/
void init(PCB *p,int *available);//初始化
void print(PCB *p,int *available);//打印
void update(PCB *p,int *avilable);//更新操作
int safe_fcs(PCB *p,int *available_temp);//寻找安全序列
void copy_func(PCB *p1,PCB *p2,int *available,int *available_temp);//拷贝信息
/*----函数实现部分----*/
void init(MYPCB *p,int *available){
printf("初始化进程数组...\n");
printf("pname\tMax\tAllocation\n");
printf("进程名\tA B C \tA B C\n");
for(int i=0;i<N;i++){
scanf("%s",p[i].pname);
strcpy(p[i].flags,"ready");
for(int j=0;j<M;j++)
scanf("%d",&p[i].Max[j]);
for(j=0;j<M;j++)
scanf("%d",&p[i].Allocation[j]);
for(j=0;j<M;j++)
p[i].Need[j] = p[i].Max[j] - p[i].Allocation[j];
}
printf("初始化可用资源...\n");
printf("Available...\nA B C\n");
for(int j=0;j<M;j++)
scanf("%d",&available[j]);
}
void copy_func(PCB *p1,PCB *p2,int *available,int *available_temp){
//p1->p2,A->A_temp;
int j=0;
for(int i=0;i<N;i++){
strcpy(p2[i].pname,p1[i].pname);
strcpy(p2[i].flags,p1[i].flags);
for(j=0;j<M;j++){
p2[i].Max[j] = p1[i].Max[j];
p2[i].Allocation[j] = p1[i].Allocation[j];
p2[i].Need[j] = p1[i].Need[j];
}
}
for(j=0;j<M;j++)
available_temp[j] = available[j];//将Available拷贝成副本Available_temp
}
void update(PCB *p,int *available){
char pname[5]={'\0'};
int acquire[M]={'0'};
int i=0,j=0;
loop1:
printf("请您输入进程名pname:...\n");
scanf("%s",pname);
printf("请您输入要各种资源的申请实例数:...\n(A B C)\n");
for(j=0;j<M;j++)
scanf("%d",&acquire[j]);
for(i=0;i<N;i++){
if(strcmp(pname,p[i].pname)!=0)
continue;
else
break;
}
if(i<N){//i对应的那个进程就是我要申请资源的进程
for(j=0;j<M;j++){
if(strcmp(p[i].flags,"finish")==0){
printf("您输入的进程已经运行完!\n请您重新输入...\n");
goto loop1;
}
if((acquire[j] <= p[i].Need[j])&&(acquire[j] <= available[j]))
continue;
else{
printf("您输入的申请资源过多!\n请您重新输入...\n");
goto loop1;
}
}
if(j==M){//满足要求的申请,修改进程信息
for(j=0;j<M;j++){
p[i].Need[j] -= acquire[j];
p[i].Allocation[j] += acquire[j];
available[j] -= acquire[j];
}
}
for(j=0;j<M;j++){//判断刚刚申请资源的进程是否已经达到了Max值
if(p[i].Max[j] == p[i].Allocation[j])
continue;
else{
strcpy(p[i].flags,"waiting");//继续等待下一次的分配
break;
}
}
if(j==M){//表示申请资源之后的进程已经饱和了,达到了Max值
for(int k=0;k<M;k++){//将该进程所占有的资源释放给操作系统
available[k] += p[i].Allocation[k];
p[i].Allocation[k] = 0;
}
strcpy(p[i].flags,"finish");
}
}
else if(i==N){
printf("您输入的进程不存在!\n请您重新输入...\n");
goto loop1;
}
}
int safe_fcs(PCB *p,int *available_temp)
{//检查当前系统是否是安全的,确定不存在循环等待
int work[M];//存放系统可分配给进程的资源
int finish[N];//进程是否分配的标识信息,若finish[i]为0,则没有分配,若finish[i]为1,则已分配
int i=0,j=0;
struct pname_node{
char pname[5];
struct pname_node *next;
};//用于存放安全序列的
struct pname_node *head,h,*p1,*p2;//h为头结点
head = &h;
p1 = head;
p2 = NULL;
h.next = NULL;//初始化工作
for(j=0;j<M;j++)//初始化标识向量
work[j] = available_temp[j];
for(i=0;i<N;i++)
finish[i] = 0;//0表示还没有分配资源的进程
for(i=0;i<N;i++){
if(finish[i]==0)
{
for(j=0;j<M;j++)
{
if(p[i].Need[j] <= work[j])
continue;
else
break;
}//j=M;
if(j==M)
{//说明第i个进程的Need的三个资源都小于work的三个可用资源
for(int k=0;k<M;k++)
work[k] += p[i].Allocation[k];//work的值一直增大到(A=10,B=5,C=7)
finish[i] = 1;
p2 = (struct pname_node*)malloc(sizeof(struct pname_node));
strcpy(p2->pname,p[i].pname);
p1->next=p2;
p1=p2;
p2->next=NULL;
p2=NULL;
i=-1;//从新检索并分配资源(i=0;????)
}
}
}
free(p2);
for(i=0;i<N;i++){
if(finish[i]==1)
continue;
else
break;
}
if(i==N)
{
printf("安全序列是这个:(");
for(p1=head->next;p1!=NULL;p1=p1->next)
printf("%s ",p1->pname);
printf(")的状态如下:...\n");
return 1;
}
else
return 0;
}
void print(PCB *p,int *available){
printf("pname\tMax\tAllocation\tNeed\tflags\tAvailable\n");
printf("\tA B C \tA B C \t\tA B C");
for(int i=0;i<N;i++){
printf("\n%s\t",p[i].pname);
int j=0;
printf("%d %d %d\t",p[i].Max[j],p[i].Max[j+1],p[i].Max[j+2]);
printf("%d %d %d\t\t",p[i].Allocation[j],p[i].Allocation[j+1],p[i].Allocation[j+2]);
printf("%d %d %d\t",p[i].Need[j],p[i].Need[j+1],p[i].Need[j+2]);
printf("%s\t",p[i].flags);
if(i==N-1)
printf("%d %d %d\n",available[j],available[j+1],available[j+2]);
}
}
int main()
{
system("color 02");
PCB p[N]={'\0'},p_temp[N]={'\0'};
int Available[M];
int Available_temp[M];//资源副本
int i=0,j=0,flag=1;//flag 进程是否资源分配完了的标识
int STEPS=0;
init(p,Available);
print(p,Available);
printf("\n银行家开始给各个商家贷款了!\n\n");
while(flag){
loop:
copy_func(p,p_temp,Available,Available_temp);
update(p_temp,Available_temp);//进行交互式输入申请资源实例数
for(i=0;i<N;i++)
{
if(strcmp(p_temp[i].flags,"finish")==0)
continue;
else
break;
}
if(i==N){//如果全部进程状态都为finish状态,那么将flag置为0,跳出while循环
copy_func(p_temp,p,Available_temp,Available);
flag = 0;
}
else
{
if(safe_fcs(p_temp,Available_temp)==1){//如存在安全序列的话将其打印接着执行分配资源
STEPS++;
printf("\nSTEPS=%d\n",STEPS);
copy_func(p_temp,p,Available_temp,Available);
print(p,Available);
}
else{
printf("\n因为这样贷款会使银行处于不安全的状态!\n请您重新输入...\n");
goto loop;
}
}
}
STEPS++;
printf("银行家总共分配了%d次\n",STEPS);
print(p,Available);
printf("\n银行贷款分配完事了!\n");
return 0;
}
运行过程如下:
图(1):初始化数据
图(2):打印刚才初始化的数据
图(3):p3申请了(0 1 0)资源后的状态
图(4):p1申请了(1 0 0)资源后的状态
图(5):p3又申请了(0 0 1)资源后的状态
图(6):p4申请了(2 2 1)资源后的状态
图(7):p4又申请了(2 1 0)资源后的状态
图(8):p0申请了(2 0 1)资源后的状态
图(9):p1又申请了(0 2 2)资源后的状态
图(10):p0又申请了(2 3 2)资源后的状态
图(11):p0又申请了(3 1 0)资源后的状态
图(12):p2又申请了(4 0 0)资源后的状态
图(13):p2又申请了(1 0 0)资源后的状态
图(14):分配完事了