#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define PROCESS_NUMBER 5 /*進程數*/
#define RESOURCE_NUMBER 3 /*資源數*/
#define true 1
#define false 0
typedef int bool;
//系統可用資源向量
int Available[RESOURCE_NUMBER] = {4,5,3};
//最大需求向量
int Max[PROCESS_NUMBER][RESOURCE_NUMBER] = {
{8,4,2},
{3,3,2},
{9,0,2},
{2,1,2},
{4,3,3},
};
//資源分配向量
int Allocation[PROCESS_NUMBER][RESOURCE_NUMBER] = {
{0,1,1},
{2,0,0},
{2,0,2},
{2,1,1},
{0,0,2},
};
//需求向量
int Need[PROCESS_NUMBER][RESOURCE_NUMBER];
//比較兩個一維數組
//判斷 a >= b ?
bool compare(int *a,int *b,int n)
{
int i;
for(i = 0;i < n;i++)
if(a[i] < b[i])
return false;
return true;
}
//一維數組加法
//a = a + b
void add(int *a,int *b,int n)
{
int i ;
for(i = 0;i < n;i++)
a[i] += b[i];
}
//一維數組減法
//a = a - b
void substract(int *a,int *b,int n)
{
int i;
for(i = 0;i < n;i++)
a[i] -= b[i];
}
//將數組b的值賦給a,n爲數組的大小
void assign(int *a,int *b,int n)
{
int i;
for(i = 0;i < n;i++)
a[i] = b[i];
}
//判斷是否是安全狀態
//av 可用資源矩陣
//sp 記錄安全路徑
bool issafe(int *sp)
{
int i;
int count = 0; /*記錄finish[i] = true 的個數*/
int n = 0;
int work[RESOURCE_NUMBER];
bool finish[PROCESS_NUMBER];
//work = av;
assign(work,Available,RESOURCE_NUMBER);
//初始化標記 finish
for(i = 0;i < PROCESS_NUMBER;i++)
finish[i] = false;
//n爲進程的個數
//循環最多執行n次
n = PROCESS_NUMBER;
while(n--)
for(i = 0;i < PROCESS_NUMBER;i++)
//判斷能否滿足進程i的要求
//work >= Need[i] ?
if(finish[i]== false && compare(work,Need[i],RESOURCE_NUMBER))
{
//分配,待進程完成後再釋放
add(work,Allocation[i],RESOURCE_NUMBER);
finish[i] = true;
//記錄安全路徑
sp[count] = i;
//能滿足的進程數+1
count++;
}
if(count >= PROCESS_NUMBER)
return true;
else
return false;
}
//請求分配
//pid進程,r請求向量,n資源個數
bool request(int pid,int * r,int n)
{
int i;
//記錄安全路徑
int sp[5];
if(compare(Need[pid],r,n) == true &&compare(Available,r,n)==true)
{
//嘗試分配資源
substract(Available,r,RESOURCE_NUMBER);
add(Allocation[pid],r,RESOURCE_NUMBER);
substract(Need[pid],r,RESOURCE_NUMBER);
//判斷是否是安全狀態
if(issafe(sp))
{
//打印安全路徑
printf("Security Path:\n\t");
for(i = 0;i < PROCESS_NUMBER;i++)
printf("p%d ",sp[i]);
printf("\n");
//可以分配
return true;
}
else
{
//不分配
//恢復到分配前的狀態
add(Available,r,RESOURCE_NUMBER);
substract(Allocation[pid],r,RESOURCE_NUMBER);
add(Need[pid],r,RESOURCE_NUMBER);
return false;
}
}
else return false;
}
//打印一維數組
void print(int *a,int n)
{
int i;
for(i = 0;i < n;i++)
printf("%4d",a[i]);
printf("\n");
}
//提示信息
char hint()
{
char ch;
printf("\t-----Operation Hint-----\n");
//按A或a鍵自動分配資源
printf("\tA(a)--Apply For Resources automated \n");
//按H或h鍵手動分配資源
printf("\tH(h)--Apply For Resources By Human\n");
//按Q或q鍵退出
printf("\tQ(q)--quit\n");
scanf("%c",&ch);
return ch;
}
//顯示系統信息
void init()
{
int i;
int temp[RESOURCE_NUMBER];
printf("Process Numbers:%d\n Need and Allocation respectively as follow:\n",PROCESS_NUMBER);
//顯示進程最大資源需求
for(i = 0;i < PROCESS_NUMBER;i++)
{
printf("\t process%d max need:",i);
print(Max[i],RESOURCE_NUMBER);
}
printf("\n");
//計算需求向量:Need[i]=Max[i]-Allocation[i]
for(i = 0;i < PROCESS_NUMBER;i++)
{
assign(temp,Max[i],RESOURCE_NUMBER);
substract(temp,Allocation[i],RESOURCE_NUMBER);
assign(Need[i],temp,RESOURCE_NUMBER);
}
//顯示進程已分配資源
for(i = 0;i < PROCESS_NUMBER;i++)
{
printf("\t process%d allocated resources:",i);
print(Allocation[i],RESOURCE_NUMBER);
}
//顯示系統可用資源
printf("\t available resouces:\t");
print(Available,RESOURCE_NUMBER);
}
//輸入
void input(int *r,int n,int *id)
{
int i;
//提示輸入進程號
printf("please input process id(0 ~ %d):",n-1);
//從鍵盤輸入進程號
scanf("%d",id);
//從鍵盤輸入該進程的所需資源數目
for(i=0;i<n;i++)
{
printf("\nthe numbers of needed resource%d(int):",i);
scanf("%d",&r[i]);
}
//顯示剛纔所輸入的數據
printf("\ndata you inputed :Request[%d](",*id);
for(i=0;i<n;i++)
printf("%d ",r[i]);
printf(")\n");
}
//檢查輸入
bool check(int id,int *r,int n)
{
int i;
//判斷申請資源數目是否合法
for (i=0;i<n;i++)
if(r[i]<0)
return false;
//判斷進程號是否合法
if(id >=PROCESS_NUMBER)
return false;
else
return true;
}
int main()
{
//進程id
int id;
//控制字符
char control;
//資源請求向量
int r[3];
//顯示開始信息
init();
//隨機數初始化
srand((int)time(0));
//主控過程
while(1)
{
//提示
control = hint();
if(control == 'a' || control == 'A')
{
//隨機申請資源
id = rand()%5;
r[0] = rand()%5;
r[1] = rand()%5;
r[2] = rand()%5;
//顯示申請信息
printf("\tRequest[%d](%d,%d,%d)\n",id,r[0],r[1],r[2]);
if(request(id,r,RESOURCE_NUMBER))
printf("Alloc Success!\n");
else
printf("Alloc Failed!\n");
}
else if(control == 'h' || control == 'H')
{
//輸入申請信息
input(r,RESOURCE_NUMBER,&id);
//檢查輸入是否合法
if(check(id,r,RESOURCE_NUMBER) == false)
{
printf("\nInput Error!please reinput !\n");
continue;
}
//執行
if(request(id,r,RESOURCE_NUMBER))
printf("Request Secceed!\n");
else
printf("Request Fail!\n");
}
else if (control == 'q' || control == 'Q')
exit(0);
//顯示當前系統資源和進程情況
//顯示可用資源情況
printf("Available Resources\n");
print(Available,RESOURCE_NUMBER);
//顯示資源最大需求
printf("process%d max need\n",id);
print(Max[id],RESOURCE_NUMBER);
//顯示已分配資源情況
printf("process%d allocated resources\n",id);
print(Allocation[id],RESOURCE_NUMBER);
}
return 0;
}