銀行家算法

/*----銀行家算法-----*/
#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;
}



運行過程如下:

spacer.gif

圖(1):初始化數據

spacer.gif

圖(2):打印剛纔初始化的數據

spacer.gif

圖(3):p3申請了(0 1 0)資源後的狀態

spacer.gif

圖(4):p1申請了(1 0 0)資源後的狀態

spacer.gif

圖(5):p3又申請了(0 0 1)資源後的狀態

spacer.gif

圖(6):p4申請了(2 2 1)資源後的狀態

spacer.gif

圖(7):p4又申請了(2 1 0)資源後的狀態

spacer.gif

圖(8):p0申請了(2 0 1)資源後的狀態

spacer.gif

圖(9):p1又申請了(0 2 2)資源後的狀態

spacer.gif

圖(10):p0又申請了(2 3 2)資源後的狀態

spacer.gif

圖(11):p0又申請了(3 1 0)資源後的狀態

spacer.gif

圖(12):p2又申請了(4 0 0)資源後的狀態

spacer.gif

圖(13):p2又申請了(1 0 0)資源後的狀態

spacer.gif

圖(14):分配完事了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章