介绍
data.h
#ifndef _Data_h_
#define _Data_h_#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define ElemType PCB
#define Status int
#define true 1
#define false 0
#define OK 1
#define ERROR 0
#define RESOURCE_NUM 3
#define MAX_RESOURCE_A_NUM 10
#define MAX_RESOURCE_B_NUM 5
#define MAX_RESOURCE_C_NUM 7
#define NAME_MAXSIZE 20
#define PCB_Num 5
typedef struct{int MaxNum[RESOURCE_NUM]; //需要每项资源个数int AllocationNum[RESOURCE_NUM]; //已占用每项资源个数int NeedNum[RESOURCE_NUM]; //还需要的每项资源个数
}ResourceList;typedef struct
{char Name[NAME_MAXSIZE]; //进程名ResourceList resList; //资源清单
}PCB;typedef struct Node
{ElemType data;struct Node * Next;
}LNode,*LinkList;#endif
chainlist.h
#ifndef _ChainList_h_
#define _ChainList_h_#include "Data.h"Status Init(LinkList *L);
void Assignment(ElemType *e1, ElemType e2);
Status ListInsert_L(LinkList L,ElemType e);#endif
实现
ProPCB.h
#ifndef _ProPCB_h_
#define _ProPCB_h_#include "ChainList.h"
#include <string.h>
//上队列
Status GetProcess(LinkList Q,ElemType e);
//银行家算法
Status BankerAlgorithm(int *Allocation, int *Request,int i, int *Need, int *Available);
//安全性检测算法
Status SecurityCheck(int *Allocation,int *Need, int *Available);
//分配资源
Status AllocateResource(LinkList PCBdata , int pos , int *Request);
//获取资源矩阵
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available);
//打印进程资源信息
void PrintProQueue(LinkList L, int *A);
//得到指定PCB名的位置
void GetPos(LinkList L, char *name, int len, int *pos);
//对当前的请求进行预分配
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available);
//正式分配算法
void GrantSource(LinkList L, int *Request, int pos, int *Available);#endif
chainlist.c
#include "ChainList.h"
extern int CPUUsedTime;
Status Init(LinkList *L)
{*L = (LinkList)malloc(sizeof(LNode));strcpy((*L)->data.Name, "");(*L)->Next = NULL;return OK;
}void Assignment(ElemType *e1, ElemType e2)
{int i = 0;strcpy(e1->Name,e2.Name);for(i = 0; i < RESOURCE_NUM; ++i){e1->resList.AllocationNum[i] = e2.resList.AllocationNum[i];e1->resList.MaxNum[i] = e2.resList.MaxNum[i];e1->resList.NeedNum[i] = e2.resList.NeedNum[i];}
}Status ListInsert_L(LinkList L,ElemType e) //这样修改应该不对 p = *L出错
{LinkList p = L, s;while (p->Next) p = p->Next;s = (LinkList)malloc(sizeof(LNode));Assignment(&s->data, e);s->Next = p->Next;p->Next = s;return OK;
}
ProPCB.c
#include "ProPCB.h"Status GetProcess(LinkList Q,ElemType e)
{return ListInsert_L(Q, e);
}Status AllocateResource(LinkList PCBdata , int pos , int *Request)
{int i = 1;LNode *p = PCBdata->Next;while (p && i < pos){p = p->Next;++i;}if(!p || i > pos)return ERROR;for (i = 0; i < RESOURCE_NUM; ++i){p->data.resList.AllocationNum[i] += Request[i];p->data.resList.NeedNum[i] -= Request[i];}return OK;
}
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available)
{LNode *p;int i, j, c = RESOURCE_NUM;Available[0] = Available[1] = Available[2] = 0;for(p = PCBdata->Next, i = 0; p; p = p->Next, ++i){for(j = 0; j < RESOURCE_NUM; ++j){Max[i * c + j] = p->data.resList.MaxNum[j];Allocation[i * c + j] = p->data.resList.AllocationNum[j];Need[i * c + j] = p->data.resList.NeedNum[j];}Available[0] += Allocation[i * c + 0];Available[1] += Allocation[i * c + 1];Available[2] += Allocation[i * c + 2];}Available[0] = MAX_RESOURCE_A_NUM - Available[0];Available[1] = MAX_RESOURCE_B_NUM - Available[1];Available[2] = MAX_RESOURCE_C_NUM - Available[2];
}void PrintProQueue(LinkList L,int *available)
{int i = 0;L = L->Next;printf(" -------------------------------------------------------------\n");printf("|进程名 | Max | Allocation | Need | Available |\n");printf("| | A B C | A B C | A B C | A B C |\n");while(L){printf("| %s | %d %d %d | %d %d %d | %d %d %d | %d %d %d |\n",L->data.Name, L->data.resList.MaxNum[0], L->data.resList.MaxNum[1], L->data.resList.MaxNum[2],L->data.resList.AllocationNum[0],L->data.resList.AllocationNum[1],L->data.resList.AllocationNum[2],L->data.resList.NeedNum[0],L->data.resList.NeedNum[1],L->data.resList.NeedNum[2],available[0], available[1], available[2]);L = L->Next;}printf(" -------------------------------------------------------------\n");}//安全性检测算法
Status SecurityCheck(int *Allocation,int *Need, int *Available)
{/ 以下补充 //int work[RESOURCE_NUM];int Finish[PCB_Num];int k, i, j, t, f;int flag;//初始化工作向量和标记数组memcpy(work, Available, sizeof work);memset(Finish, 0, sizeof Finish);//最多检测PCB_Num次for(k = 0; k < PCB_Num; ++k){flag = 0;for(i = 0; i < PCB_Num; ++i){//已经被访问if(Finish[i]){continue;}//检测是否所有资源都能被分配for(j = 0; j < RESOURCE_NUM; ++j){if(!(Need[i * 3 + j] <= work[j])){break;}}//可以满足,回收if(j == RESOURCE_NUM){for(t = 0; t < RESOURCE_NUM; ++t){work[t] += Allocation[i * 3 + t];}Finish[i] = 1;flag = 1;break;}}//为进行分配,跳出循环if(!flag){break;}}for(f = 0; f < PCB_Num; ++f){//只要有一个进程不满足,跳出循环if(!Finish[f]){return ERROR;}}return OK;
}//银行家算法
Status BankerAlgorithm(int* Allocation, int *Request,int pos,int *Need, int *Available)
{/ 以下补充 //int i;//检查请求的是否大于需要的for(i = 0; i < RESOURCE_NUM; ++i){if(Request[i] > Need[pos*3 + i]){return ERROR;}}//检查请求的是否大于可分配的for(i = 0; i < RESOURCE_NUM; ++i){if(Request[i] > Available[i]){return ERROR;}}//进行预分配PreGrant(Allocation, Request, pos, Need, Available);//进行安全性检测if(!SecurityCheck(Allocation, Need, Available)){return ERROR;}return OK;
}//根据PCB的名字得到该PCB在链表中的位置
void GetPos(LinkList L, char *name, int len, int *pos)
{LinkList p = L->Next;char PcbName[NAME_MAXSIZE];memcpy(PcbName, name, (len + 1) * sizeof(char));(*pos) = 0;while(p){if(strcmp(p->data.Name, PcbName)){(*pos)++;p = p->Next;} else {break;}}
}//预分配算法
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available){int i;//1. Need减去请求的for(i = 0; i < RESOURCE_NUM; ++i){Need[pos*3 + i] -= Request[i];}//2. Available减去请求的for(i = 0; i < RESOURCE_NUM; ++i){Available[i] -= Request[i];}//3. Allocation加上请求的for(i = 0; i < RESOURCE_NUM; ++i){Allocation[pos*3 + i] += Request[i];}
}/*** 1.首先对请求资源的进程进行分配资源* 2.如果给该进程分配资源之后,该进程所需的资源等于已经得到的资源,那么对其拥有的资源进行回收*///正式分配算法,pos从0开始标记
void GrantSource(LinkList L, int *Request, int pos, int *Available){LinkList p = L->Next;int tag = 0;int i;int flag = 0;if(tag < pos && NULL != p){p = p->Next;tag++;}if(p){//已获得的加上请求的for(i = 0; i < RESOURCE_NUM; ++i){p->data.resList.AllocationNum[i] += Request[i];}//还需要的减去请求的for(i = 0; i < RESOURCE_NUM; ++i){p->data.resList.NeedNum[i] -= Request[i];}//可利用的减去请求的for(i = 0; i < RESOURCE_NUM; ++i){Available[i] -= Request[i];}//如果进行分配之后该进程最大所需资源数目等于已获得的资源数目,则对资源进行回收flag = 0;for(i = 0; i < RESOURCE_NUM; ++i){if(p->data.resList.AllocationNum[i] != p->data.resList.MaxNum[i]){flag = 1;break;}}if(!flag){for(i = 0; i < RESOURCE_NUM; ++i){Available[i] += p->data.resList.AllocationNum[i];}}}
}
main
#include "ProPCB.h"void InputData(LinkList * pPCBdata)
{ElemType e = {{0},{{0},{0},{0}}};strcpy(e.Name,"P0");e.resList.MaxNum[0] = 7; e.resList.MaxNum[1] = 5; e.resList.MaxNum[2] = 3;e.resList.AllocationNum[0] = 0;e.resList.AllocationNum[1] = 1;e.resList.AllocationNum[2] = 0;e.resList.NeedNum[0] = 7; e.resList.NeedNum[1] = 4; e.resList.NeedNum[2] = 3; GetProcess(*pPCBdata,e);strcpy(e.Name,"P1");e.resList.MaxNum[0] = 3; e.resList.MaxNum[1] = 2; e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 2;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 0;e.resList.NeedNum[0] = 1; e.resList.NeedNum[1] = 2; e.resList.NeedNum[2] = 2; GetProcess(*pPCBdata,e);strcpy(e.Name,"P2");e.resList.MaxNum[0] = 9; e.resList.MaxNum[1] = 0; e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 3;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 2;e.resList.NeedNum[0] = 6; e.resList.NeedNum[1] = 0; e.resList.NeedNum[2] = 0; GetProcess(*pPCBdata,e);strcpy(e.Name,"P3");e.resList.MaxNum[0] = 2; e.resList.MaxNum[1] = 2; e.resList.MaxNum[2] = 2;e.resList.AllocationNum[0] = 2;e.resList.AllocationNum[1] = 1;e.resList.AllocationNum[2] = 1;e.resList.NeedNum[0] = 0; e.resList.NeedNum[1] = 1; e.resList.NeedNum[2] = 1; GetProcess(*pPCBdata,e);strcpy(e.Name,"P4");e.resList.MaxNum[0] = 4; e.resList.MaxNum[1] = 3; e.resList.MaxNum[2] = 3;e.resList.AllocationNum[0] = 0;e.resList.AllocationNum[1] = 0;e.resList.AllocationNum[2] = 2;e.resList.NeedNum[0] = 4; e.resList.NeedNum[1] = 3; e.resList.NeedNum[2] = 1; GetProcess(*pPCBdata,e);
}
int main(void)
{LinkList PCBdata; //PCBdata里面存放原始数据ElemType e = {{0},{{0},{0},{0}}};char PcbName[NAME_MAXSIZE], chioce;int Max[PCB_Num][RESOURCE_NUM] = {0}, Allocation[PCB_Num][RESOURCE_NUM] = {0};int Need[PCB_Num][RESOURCE_NUM] = {0}, Available[RESOURCE_NUM] = {0};int Request[RESOURCE_NUM] = {0}, pos = 0;LNode *p = NULL;int i;/ 以下补充 ////初始化就绪队列Init(&PCBdata);//数据输入InputData(&PCBdata);while(1){//获取所有PCB中的资源信息GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);//打印当前系统的状态PrintProQueue(PCBdata, Available);//接受请求printf("请输入申请资源的进程名,资源A,资源B,资源C申请量(空格隔开):");scanf("%s", PcbName);for(i = 0; i < RESOURCE_NUM; ++i){scanf("%d", &Request[i]);}//获取相应的PCB在链表中的位置GetPos(PCBdata, PcbName, strlen(PcbName), &pos);//跑银行家算法,根据返回值的状态判断是否安全,//如果安全,进行正式分配,否则仅仅打印不安全信息if(BankerAlgorithm(*Allocation, Request, pos, *Need, Available)){//正式分配资源GrantSource(PCBdata, Request, pos, Available);//分配完成后,打印资源的信息GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);PrintProQueue(PCBdata, Available);printf("请安任意键继续. . . ");getchar();getchar();} else {printf("不安全,不可分配!\n");}}return 0;
}