最近学习操作系统到了死锁这一部分,为了避免死锁,系统可以采用银行家算法来分配进程申请的资源。于是我参照教材,用C语言基本实现了这个算法。(不过我并没有做过多测试,代码应该没啥大问题吧…)
#include<stdio.h>
#include<stdlib.h>
#define MAXRESOURCE 100 //最大资源种类
#define MAXPROCESS 100 //最大进程数量
typedef struct SystemState //定义系统状态
{
int resTypeAmount, processAmount;
int resource[MAXRESOURCE]; //系统资源总量
int available[MAXRESOURCE]; //系统当前可用资源
int claim[MAXPROCESS][MAXRESOURCE]; //进程n请求资源m的总量
int alloc[MAXPROCESS][MAXRESOURCE]; //进程n已有资源m的数量
} State;
void InitState(); //初始化状态
void Request(int, int*); //进程申请资源
int ResourceAllocation(int, int[]); //资源分配算法
int Safe(state); //测试安全算法(银行家算法
void ShowState(State);
State state;
int main()
{
int processID = -1, request[MAXPROCESS];
int i, j;
//初始化状态
InitState();
//进程申请资源分配
Request(&processID, &request);
//进行安全性检测
ResourceAllocation(processID, request);
}
void InitState()
{
int i, j;
printf("输入资源种数 resTypeAmout = "); scanf("%d", &state.resTypeAmount);
printf("输入进程总数 processAmount = "); scanf("%d", &state.processAmount);
//claim矩阵
printf("输入claim矩阵: \n");
for (i = 0; i < state.processAmount; i++)
{
for (j = 0; j < state.resTypeAmount; j++)
{
scanf("%d", &state.claim[i][j]);
}
}
//alloc矩阵
printf("输入allocation矩阵: \n");
for (i = 0; i < state.processAmount; i++)
{
for (j = 0; j < state.resTypeAmount; j++)
{
scanf("%d", &state.alloc[i][j]);
}
}
//resource向量
printf("输入resource向量: \n");
for (i = 0; i < state.resTypeAmount; i++)
{
scanf("%d", &state.resource[i]);
}
//available向量
printf("输入available向量: \n");
for (i = 0; i < state.resTypeAmount; i++)
{
scanf("%d", &state.available[i]);
}
//ShowState(state);
}
void Request(int* processID, int* request)
{
int i;
printf("输入需要申请资源的进程id: "); scanf("%d", processID);
printf("输入进程%d的request向量: ", *processID);
for (i = 0; i < state.resTypeAmount; i++)
{
scanf("%d", &request[i]);
}
}
int ResourceAllocation(int processID, int request[])
{
int i;
//1.合法性检查
for (i = 0; i < state.resTypeAmount; i++)
{
if (state.alloc[processID][i] + request[i] > state.claim[processID][i]) //申请资源量 + 已占有资源量 <= 预先声明量
{
printf("申请失败!!!进程%d申请资源%d总和大于预先声明值\n", processID, i);
return 0;
}
else if (request[i] > state.available[i]) //申请资源量 < 系统当前可用量
{
printf("申请失败!!!进程%d申请资源%d的值大于系统目前可使用量,该进程将被阻塞\n", processID, i);
return 0;
}
}
//2.假定分配
for (i = 0; i < state.resTypeAmount; i++)
{
state.alloc[processID][i] += request[i];
state.available[i] -= request[i];
}
//3.安全性检测
int order[MAXPROCESS];
if (Safe(state, order) == 0)
{
//安全
printf("\n同意请求! 安全序列是: <%d", order[0]);
for (i = 1; i < state.processAmount; i++)
{
printf(", %d", order[i]);
}
printf(">\n");
ShowState(state);
}
else
{
//复原
state.alloc[processID][i] -= request[processID];
state.available[i] += request[processID];
//阻塞进程
printf("拒绝请求! 系统可能死锁,现已阻塞该进程\n");
}
}
int Safe(State s, int* order)
{
int currentAvail[MAXRESOURCE]; //当前剩余资源
int restProcess[MAXPROCESS]; //标记每个进程结束与否
int rest; //未完成的进程数量
int possible = 1, found, done;
int i, j, p, k = 0;
for (i = 0; i < s.resTypeAmount; i++)
{
currentAvail[i] = s.available[i];
}
for (i = 0; i < s.processAmount; i++)
{
restProcess[i] = 0; //所有进程都未执行完毕
}
rest = s.processAmount;
while (possible)
{
found = 0;
for (i = 0; i < s.processAmount && !found; i++) //想寻找一个可以完成的进程
{
if (restProcess[i] == 0)
{
done = 1;
for (j = 0; j < s.resTypeAmount&&done; j++)
{
if (s.claim[i][j] - s.alloc[i][j] > currentAvail[j]) //若 进程需要资源 > 系统剩余资源,无法执行该进程
done = 0;
}
if (done)
{
found = 1;
p = i;
}
}
}
if (found) //找到了一个可以完成的进程
{
for (j = 0; j < s.resTypeAmount; j++)
{
currentAvail[j] += s.alloc[p][j]; //回收资源
}
restProcess[p] = 1; //标记该进程已结束
--rest; //剩余进程-1
order[k++] = p; //记录安全序列
}
else
{
possible = 0;
}
}
return rest;
}
void ShowState(State s)
{
int i, j;
printf("\nclaim矩阵:\n");
for (i = 0; i < s.processAmount; i++)
{
for (j = 0; j < s.resTypeAmount; j++)
{
printf("%d ", s.claim[i][j]);
}
printf("\n");
}
printf("\nallocation矩阵:\n");
for (i = 0; i < s.processAmount; i++)
{
for (j = 0; j < s.resTypeAmount; j++)
{
printf("%d ", s.alloc[i][j]);
}
printf("\n");
}
printf("\nresource向量:\n");
for (i = 0; i < s.resTypeAmount; i++)
{
printf("%d ", s.resource[i]);
}
printf("\navailable向量:\n");
for (i = 0; i < s.resTypeAmount; i++)
{
printf("%d ", s.available[i]);
}
printf("\n");
}
运行效果如下图所示: