介紹
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;
}
?