#include <stdlib.h>
#include <stdio.h>
#include <malloc/malloc.h>
#define SourceType 3
#define ProcessNum 5
//第SourceNum类可用资源数:
typedef struct Available{
int Available[SourceType];
}Ava;
//进程ProcessNum对资源SourceNum类资源的最大需求:
typedef struct Max{
int Max[ProcessNum][SourceType];
}Max;
//进程ProcessNum已占有资源SourceNum类资源的数量:
typedef struct Allocation{
int Allocation[ProcessNum][SourceType];
}Alloc;
//进程ProcessNum还需要多少SourceNum资源:
typedef struct Need{
int Need[ProcessNum][SourceType];
}Need;
int check(Ava * ava,Need * need,Alloc * allo){
//初始化Finish:
int Finish[ProcessNum];
for (int i=0; i<ProcessNum; i++) {
Finish[i] = 0;
}
//初始化Work:
int Work[SourceType];
for (int j=0; j<SourceType; j++) {
Work[j] = ava->Available[j];
}
//生成p数组(即安全序列):
int p[ProcessNum];
for (int pp = 0; pp<ProcessNum; pp++) {
p[pp] = 0;
}
//复制need:
Need * needCp = (Need*)malloc(sizeof(Need));
for (int i=0; i<ProcessNum; i++) {
for (int j=0; j<SourceType; j++) {
needCp->Need[i][j] = need->Need[i][j];
}
}
for (int ii=0; ii<ProcessNum; ii++) {
int outCheckSum = 0;
//从0号进程开始查找:
for (int i=0; i<ProcessNum; i++) {
int checkSum = 0;
for (int j=0; j<SourceType; j++) {
if (needCp->Need[i][j] <= Work[j]) {
checkSum+=1;
}
}
if (checkSum == SourceType) {
printf(“work = “);
for (int j=0; j<SourceType; j++) {
//使这个进程的need不会再被遍历:
needCp->Need[i][j] += 10;
printf(” %d “,Work[j]);
Work[j] = Work[j] + allo->Allocation[i][j];
Finish[i] = 1;
p[ii]=i;
}
//跳出循环:
i=ProcessNum;
}
outCheckSum = checkSum;
}
if (outCheckSum < SourceType) {
free(needCp);
return 0;
}
printf(“p[ii] = %d \n”,p[ii]);
}
free(needCp);
return 1;
}
int main(int argc, const char * argv[]) {
/************************** 初始化 ****************************/
/*已知有3个并发进程共享10个系统资源(因此SourceNum=1,ProcessNum=3)*/
//初始化系统资源数Available:
printf(“输入系统原有资源数:\n”);
Ava * ava = (Ava*)malloc(sizeof(Ava));
for (int i=0; i<SourceType; i++) {
scanf(“%d”,&ava->Available[i]);
}
//Allocation数组存放各进程申请的各SourceType类的资源数:
Alloc * allo = (Alloc*)malloc(sizeof(Alloc));
int sum[SourceType];
for (int i=0; i<SourceType; i+=1) {
sum[i] = 0;
}
printf(“输入各进程动态申请资源数组:\n”);
for (int i=0; i<ProcessNum; i++) {
printf(“进程 %d : \n”,i);
for (int j=0; j<SourceType; j++) {
scanf(“%d”,&allo->Allocation[i][j]);
sum[j] = sum[j] + allo->Allocation[i][j];
}
}
//初始化Max数组,并生成Need数组:
Max * max = (Max*)malloc(sizeof(Max));
Need * need = (Need*)malloc(sizeof(Need));
printf(“输入各进程对于各资源的最大需求:\n”);
for (int i=0; i<ProcessNum; i++) {
printf(“进程 %d : \n”,i);
for (int j=0; j<SourceType; j++) {
scanf(“%d”,&max->Max[i][j]);
if (max->Max[i][j] > ava->Available[j]) {
printf(“申请最大资源数大于系统现有资源数!”);
return –1;
}else{
need->Need[i][j] = max->Max[i][j] – allo->Allocation[i][j];
}
}
}
printf(“计算出现有的SourceType类的资源数:\n”);
for (int i=0; i<SourceType; i++) {
ava->Available[i] = ava->Available[i] – sum[i];
printf(” %d “,ava->Available[i]);
}
printf(“\n”);
/************************** 初始安全检测 ****************************/
int checkResult = check(ava,need,allo);
if (checkResult) {
printf(“Safe!\n”);
}else{
printf(“Unsafe!\n”);
return –1;
}
/************************** 开始运行 ****************************/
//输入第i号进程的Request向量:
int Request[SourceType];
int RequestNum = 0;
while (RequestNum != –1) {
//输入第RequestNum号进程申请资源:
printf(“输入第RequestNum号进程申请资源\n”);
scanf(“%d”,&RequestNum);
if (RequestNum == –1) break;
//对第j类资源的申请量:
printf(“输入对第j类资源的申请量:\n”);
for (int jj=0; jj<SourceType; jj++) {
scanf(“%d”,&Request[jj]);
}
//判断申请量是否合格:
int checkAll = 0;//如果等于SourceType,说明下面的条件每一类资源都成立:
for (int jj = 0; jj<SourceType; jj++) {
if ((Request[jj] <= need->Need[RequestNum][jj]) && (Request[jj] <= ava->Available[jj])) {
checkAll+= 1;
}
}
//对资源进行试探性分配:
if (checkAll == SourceType) {
for (int jj=0; jj<SourceType; jj++) {
allo->Allocation[RequestNum][jj] = allo->Allocation[RequestNum][jj] + Request[jj];
need->Need[RequestNum][jj] = need->Need[RequestNum][jj] – Request[jj];
ava->Available[jj] = ava->Available[jj] – Request[jj];
}
}else{
printf(“不安全!\n”);
continue;
}
//安全检查:
if (check(ava, need, allo)) {
printf(“安全!\n”);
}else{
printf(“不安全!\n”);
//撤销刚才的试探性分配:
for (int jj=0; jj<SourceType; jj++) {
allo->Allocation[RequestNum][jj] = allo->Allocation[RequestNum][jj] – Request[jj];
need->Need[RequestNum][jj] = need->Need[RequestNum][jj] + Request[jj];
ava->Available[jj] = ava->Available[jj] + Request[jj];
}
}
}
return 0;
}