#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define RESOURCE_MAXNUM 3 //资源数
#define THREAD_MAXNUM 5 //进程数
//定义可利用资源向量
struct Available
{
int available[RESOURCE_MAXNUM];
}res_ava;
//最大需求矩阵
struct Max
{
int max[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_max;
//已分配矩阵
struct Allocation
{
int allocation[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_all;
//需求矩阵
struct Need
{
int need[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_nee;
//临时进程的资源分配序列
int tmpSequence[THREAD_MAXNUM];
//可能的一个安全序列
int secSequence[THREAD_MAXNUM];
//找到一个安全执行序列的标志
int isFindSecQue = 0;
//定义一系操作方法
//进行显式地初始化操作
void init();
//打印操作
void printInfo();
//输入操作
void input();
//检测条件Need = Max - Allocation
int check();
//测试可得到的资源能否江足要求
int check(int threadID,int need[THREAD_MAXNUM]);
//当前待分配的进程需求
void curThreadNeed();
//更新操作
void update(int thredID,int need[THREAD_MAXNUM]);
//释放操作
void release(int threadID);
//安全性算法
int security(int sequence[THREAD_MAXNUM]);
//回溯得到进程执行序列,并执行安全性算法
void backtrack(int i);
//交换数组中指定的两个值
void swapArray(int arr[THREAD_MAXNUM],int pos1,int pos2);
//拷贝数组
void copyArray(int arr1[THREAD_MAXNUM],int arr2[THREAD_MAXNUM]);
int main()
{
init();
input();
int checkres = check();
if(checkres == 0)
{
printf("输入有问题,确认后重新输入/n");
exit(-1);
}
printInfo();
curThreadNeed();
printInfo();
printf("执行安全性算法/nENTER键继续 .../n/n");
getch();
backtrack(0);
if(isFindSecQue == 0)
printf("未找到一个安全的进程执行序列/n");
return 0;
}
void init()
{
int i,j;
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
res_all.allocation[i][j] = 0;
res_max.max[i][j] = 0;
res_nee.need[i][j] = 0;
}
tmpSequence[i] = i;
secSequence[i] = i;
}
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
res_ava.available[j] = 0;
}
}
void printInfo()
{
int i,j;
printf("**********************当前资源分配**********************/n");
printf("最大需求矩阵/t/t|分配矩阵/t/t|需求矩阵 /n");
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
printf("%d/t",res_max.max[i][j]);
}
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
printf("%d/t",res_all.allocation[i][j]);
}
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
printf("%d/t",res_nee.need[i][j]);
}
printf("/n");
}
printf("/n");
printf("可利用资源向量/t/n");
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
printf("%d/t",res_ava.available[j]);
}
printf("/n");
}
void input()
{
int i,j;
printf("输入当前可利用资源/n");
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
scanf("%d",&res_ava.available[j]);
}
printf("输入分配矩阵 /n");
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
scanf("%d",&res_all.allocation[i][j]);
}
}
printf("输入最大需求矩阵/n");
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
scanf("%d",&res_max.max[i][j]);
}
}
printf("输入需求矩阵/n");
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
scanf("%d",&res_nee.need[i][j]);
}
}
}
int check()
{
int i,j;
for(i = 0;i < THREAD_MAXNUM; ++i)
{
for(j = 0;j < RESOURCE_MAXNUM; ++j)
{
if(res_nee.need[i][j] != res_max.max[i][j] - res_all.allocation[i][j])
{
return 0;
}
}
}
return 1;
}
int check(int threadID,int need[THREAD_MAXNUM]){
int i;
for(i = 0;i<RESOURCE_MAXNUM; ++i)
{
//当前需求向量要小于可获得资源向量及相应需求向量
if(need[i] > res_ava.available[i] || need[i] > res_nee.need[threadID][i])
return 0;
}
return 1;
}
void curThreadNeed()
{
printf("输入当前进程的编号及所需的资源向量/n");
int need;
scanf("%d",&need);
int res_need[RESOURCE_MAXNUM];
int i;
for(i = 0;i < RESOURCE_MAXNUM; ++i)
{
scanf("%d",&res_need[i]);
}
printf("进程%d需要的资源向量为:/n",need);
for(i = 0;i < RESOURCE_MAXNUM; ++i)
{
printf("%d/t",res_need[i]);
}
printf("/n");
if(check(need,res_need) == 0)
{
printf("需求大于可获得的资源,请确定后再输入/n");
exit(-1);
}
//更新操作
update(need,res_need);
}
void update(int thredID,int need[THREAD_MAXNUM])
{
int j;
for(j = 0;j<RESOURCE_MAXNUM; ++j)
{
res_ava.available[j] -= need[j];
res_nee.need[thredID][j] -= need[j];
res_all.allocation[thredID][j] += need[j];
}
}
void release(int threadID)
{
int i;
for(i = 0;i < RESOURCE_MAXNUM; ++i)
{
res_ava.available[i] += res_max.max[threadID][i];
}
}
int security(int sequence[THREAD_MAXNUM])
{
//工作向量
int Work[RESOURCE_MAXNUM];
int i;
for(i = 0;i < RESOURCE_MAXNUM; ++i)
{
Work[i] = res_ava.available[i];
}
for(i = 0;i<THREAD_MAXNUM; ++i)
{
//判断当前能否分配资源
int canAllFlag = 1; //能分配的标志
int j;
for(j = 0; j< RESOURCE_MAXNUM; ++j)
{
if(res_nee.need[sequence[i]][j] > Work[j])
{
canAllFlag = 0;
break;
}
}
if(canAllFlag == 0)
return 0;
//释放资源操作
for(j = 0; j< RESOURCE_MAXNUM; ++j)
{
Work[j] += res_all.allocation[sequence[i]][j];
}
}
return 1;
}
void backtrack(int i)
{
if(i >= THREAD_MAXNUM)
{
//若此序列为安全的序列
if(security(tmpSequence) == 1)
{
isFindSecQue = 1;
copyArray(secSequence,tmpSequence);
printf("找到一个安全序列/n");
int i;
for(i = 0 ;i< THREAD_MAXNUM; ++i)
{
printf("%d/t",secSequence[i]);
}
printf("/n");
}
}
int j;
for(j = i;j<THREAD_MAXNUM; ++j)
{
swapArray(tmpSequence,i,j);
backtrack(i+1);
swapArray(tmpSequence,i,j);
}
}
void swapArray(int arr[THREAD_MAXNUM],int pos1,int pos2)
{
int tmp;
tmp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = tmp;
}
void copyArray(int arr1[THREAD_MAXNUM],int arr2[THREAD_MAXNUM])
{
int i;
for(i = 0;i < THREAD_MAXNUM; ++i)
{
arr1[i] = arr2[i];
}
}
/*
输入测例
3 3 2
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
7 4 3
1 2 2
6 0 0
0 1 1
4 3 1
1
1 0 2
*/
C语言实现操作系统银行家算法
最新推荐文章于 2023-09-23 17:47:35 发布