Input tips:
test data1:
7 5 3 0 1 0 7 4 3 3 3 2
3 2 2 2 0 0 1 2 2
9 0 2 3 0 2 6 0 0
2 2 2 2 1 1 0 1 1
4 3 3 0 0 2 4 3 1
P1 1 0 2
test data2:
7 5 3 0 1 0 7 4 3 1 0 2
3 2 2 2 0 0 1 2 2
9 0 2 3 0 2 6 0 0
2 2 2 2 1 1 0 1 1
4 3 3 0 0 2 4 3 1
test data3:
7 5 3 0 1 0 7 4 3 3 3 2
3 2 2 2 0 0 1 2 2
9 0 2 3 0 2 6 0 0
2 2 2 2 1 1 0 1 1
4 3 3 0 0 2 4 3 1
P1 5 6 7
CODE
1. Source
1.1 bankerAlgorithm.c
#include "bankerAlgorithm.h"
// safetyList is the tail of the safety process list
// processList is the head of the unchecked process list
bool isSafety(NODE* safetyList, NODE* processList, int processNum, int* available)
{
int work[3] = {0};
memcpy(work, available, 3*sizeof(int));
bool finish[processNum];
for (int i=0; i<processNum; i++)
finish[i] = false;
// ergodic the number of process times
for (int i=0; i < processNum; i++)
{
int index = 0;
int finalFlag=0;
for (NODE* head=processList->next; index < processNum; head=head->next,index++)
{
if (!finish[index])
{
bool needFlag=true;
for (int j=0; j < resourcesNum; j++) //judge whether need[j] <= work[j]
if (head->need[j] > work[j])
{
needFlag = false;
break;
}
if (needFlag) //Step3
{
for (int j=0; j < resourcesNum; j++) //work[i]=work[i]+allocation[i]
work[j] += head->allocation[j];
finish[index] = true;
safetyCheck(addNode(&safetyList, head)); // add the process into the safetyList
break; // goto Step2
}
else finalFlag++;
}
}
if (finalFlag == processNum) // at this time, process list is not safety
break;
}
bool result = true;
for (int i=0; i<processNum; i++)
result = result&&finish[i];
return result; // at this time, process list is safety
}
bool request(NODE** pHead, int* requestVector, int* available, int processNum, int requestProcess)
{
int index = 0;
NODE* tHead=*pHead;
for (; index<=requestProcess && tHead->next; tHead=tHead->next,index++)
;
int* need = tHead->need;
bool needFlag = true;
bool availableFlag = true;
for (int i=0; i < resourcesNum; i++) // judge whether request[i]<need[i]
if (requestVector[i] > need[i])
needFlag = false;
if (needFlag)
{
for (int i=0; i < resourcesNum; i++) // judge whether request[i]<available[i]
if (requestVector[i] > available[i])
availableFlag = false;
if (availableFlag)
{
NODE* newHead = NULL;
NODE* newTail = NULL;
safetyCheck(createLinked(&newHead, &newTail)); // create a new linked to virtual allocation
safetyCheck(linkedCopy(newTail, *pHead));
int newIndex = 0;
NODE* Head=newHead->next;
for (; newIndex<=requestProcess && Head->next; Head=Head->next,newIndex++)
;
for (int i=0; i < resourcesNum; i++)
{
available[i] -= requestVector[i]; // available[i] = available[i]-request[i]
Head->allocation[i] += requestVector[i]; // allocation[i] = allocation[i]+request[i]
Head->need[i] -= requestVector[i]; // need[i] = need[i]-request[i]
}
NODE* safetyListHead = NULL;
NODE* safetyListTail = NULL;
safetyCheck(createLinked(&safetyListHead, &safetyListTail));
if (isSafety(safetyListTail, newHead->next, processNum, available))
*pHead = safetyListHead; // finish the real assign
else
{
printf("WARNING!\nIt is not safety! Cannot finish the assigning! P%d will be blocked!", requestProcess);
return false;
}
}
else
{
//Pi was blocked.
printf("WARNING!\nThe request resources are more than available! Cannot finish the assigning! P%d will be blocked!", requestProcess);
return false;
}
}
else
{
printf("ERROR!\nThe request resources are more than need! System has some problem!");
return false;
}
return true;
}
1.2 linkedOperate.c
#include "linkedOperate.h"
bool createLinked(NODE** pHead, NODE** pTail)
{
*pHead = malloc(sizeof(NODE));
(*pHead)->next=NULL;
*pTail = *pHead;
return true;
}
bool addNode(NODE** pTail, NODE* data)
{
NODE *tmp = malloc(sizeof(NODE));
memcpy(tmp, data, sizeof(NODE));
tmp->next = NULL;
(*pTail)->next = tmp;
*pTail = tmp;
return true;
}
bool linkedCopy(NODE* destination, NODE* resources)
{
NODE* tail = destination;
for (NODE* resourcesHead=resources; resourcesHead->next; resourcesHead=resourcesHead->next)
{
NODE* newNode = malloc(sizeof(NODE));
memcpy(newNode, resourcesHead, sizeof(NODE));
tail->next = newNode;
tail = newNode;
}
return true;
}
void safetyCheck(bool result)
{
if (!result)
{
printf("ERROR! There are something wrong in the linkedOperate file!");
exit(0);
}
}
1.3 main.c
#include "test.h"
int main()
{
test();
}
1.4 test.c
#include "test.h"
void test()
{
int processNum = 0;
int available[3] = {0};
printStdInput();
char choice;
scanf("%c",&choice);
if (choice == '\n')
{
NODE* inHead=NULL;
NODE* inTail=NULL;
NODE* safetyListHead=NULL;
NODE* safetyListTail=NULL;
safetyCheck(createLinked(&inHead, &inTail));
safetyCheck(createLinked(&safetyListHead, &safetyListTail));
processNum = initStatusInput(&inTail, available);
if (isSafety(safetyListTail, inHead, processNum, available))
{
int index = 0;
int requestVector[resourcesNum] = {0};
printf(" At T0 time, the system is safety! The safety list is: ");
for (NODE* head=safetyListHead->next; index < processNum; head=head->next, index++)
printf("%s ",head->name);
int requestProcess = requestInput(requestVector);
if (request(&inHead, requestVector, available, processNum, requestProcess))
{
printf("*********************************************************************\n");
printf(" It can be assigned! The safety list is: ");
index = 0;
for (NODE* head=inHead->next; index < processNum; head=head->next, index++)
printf("%s ", head->name);
printf("\n\n");
}
}
else
{
printf("The system is not safety, Please try again latter!");
exit(0);
}
}
else
{
printf("*********************************************************************\n");
printf(" Will exit program. ");
exit(0);
}
}
void printStdInput()
{
printf("------------- Welcome to the Banker Algorithm Simulator!-------------\n");
printf(" Here is a example:\n");
printf("********************************************************************\n");
printf("Please input the status array of T0 time(end with EOF):\n");
printf(" PID MAX ALLOCATION NEED AVAILABLE\n");
printf(" P0 7 5 3 0 1 0 7 4 3 3 3 2\n");
printf(" P1 3 2 2 2 0 0 1 2 2\n");
printf(" P2 9 0 2 3 0 2 6 0 0\n");
printf(" P3 2 2 2 2 1 1 0 1 1\n");
printf(" P4 4 3 3 0 0 2 4 3 1\n");
printf(" P5 ^Z\n");
printf("********************************************************************\n");
printf(" At T0 time, the system is safety! The safety list is: P1 P3 P0 P2 P4\n");
printf("********************************************************************\n");
printf("Please input the request array:\n");
printf("PID request\n");
printf("P0 1 0 2\n");
printf("********************************************************************\n");
printf(" It can be assigned! The safety list is: P1 P3 P4 P0 P2\n\n");
printf("Press ENTER to input ...");
}
int initStatusInput(NODE** pTail, int* available)
{
system("cls");
int processNum = 0;
int tmp[9] = {0};
printf("------------- Welcome to the Banker Algorithm Simulator!-------------\n");
printf("Please input the status array of T0 time(end with EOF):\n");
printf(" PID MAX ALLOCATION NEED AVAILABLE\n");
printf(" P%d ", processNum);
int eof = 0;
while(~scanf("%d",&eof))
{
NODE* tmpNode = malloc(sizeof(NODE));
tmpNode->name[0] ='P';
tmpNode->name[1] = processNum + 48; // allocation PID
tmpNode->name[2] = 0;
// input data
tmp[0] = eof;
for (int i=1; i < 9; i++)
scanf("%d",&tmp[i]);
if (!processNum)
for (int i=0; i < 3; i++)
scanf("%d",&available[i]);
// assign data
for (int i=0; i < 3; i++)
tmpNode->maxNeed[i] = tmp[i];
for (int i=0; i < 3; i++)
tmpNode->allocation[i] = tmp[i + 3];
for (int i=0; i < 3; i++)
tmpNode->need[i] = tmp[i + 6];
safetyCheck(addNode(pTail, tmpNode));
printf(" P%d ", ++processNum);
}
printf("*********************************************************************\n");
return processNum;
}
int requestInput(int* request)
{
int requestProcess = 0;
printf("\n");
printf("*********************************************************************\n");
printf("Please input the request array:\n");
printf("PID request\n");
scanf("P%d", &requestProcess);
for (int i=0; i < resourcesNum; i++)
scanf("%d", &request[i]);
return requestProcess;
}
2. Headeres
2.1 bankerAlgorithm.h
#ifndef BANKERALGORITHM_H_INCLUDED
#define BANKERALGORITHM_H_INCLUDED
#include <stdio.h>
#include <stdbool.h>
#include "linkedOperate.h"
#include "safetyList.h"
#define resourcesNum 3
bool isSafety(NODE* safetyList, NODE* processList, int processNum, int* available);// Security algorithm
bool request(NODE** pHead, int* requestVector, int* available, int processNum, int requestProcess);
#endif // BANKERALGORITHM_H_INCLUDED
2.2 linkedOperate.h
#ifndef LINKEDOPERATE_H_INCLUDED
#define LINKEDOPERATE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "safetyList.h"
bool createLinked(NODE** pHead, NODE** pTail);
bool addNode(NODE** pTail, NODE* data);
bool linkedCopy(NODE* destination, NODE* resources);
void safetyCheck(bool result);
#endif // LINKEDOPERATE_H_INCLUDED
2.3 safetyList.h
#ifndef SAFETYLIST_H_INCLUDED
#define SAFETYLIST_H_INCLUDED
#define resourcesNum 3
typedef struct safetyListNode{
char name[3];
int allocation[resourcesNum];
int need[resourcesNum];
int maxNeed[resourcesNum]; //maxNeed[i] = allocation[i] + need[i]
struct safetyListNode* next;
}NODE;
#endif // SAFETYLIST_H_INCLUDED
2.4 test.h
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#define resourcesNum 3
#define normalInputNum 9
#include "safetyList.h"
#include "linkedOperate.h"
#include "bankerAlgorithm.h"
void test();
void printStdInput();
int initStatusInput(NODE** pTail, int* available);
int requestInput(int* request);
#endif // TEST_H_INCLUDED
四、参考文献
(来自网络)
[1] 当request[i] > need[i]时如何:C语言银行家算法_徐奕的专栏-CSDN博客_银行家算法代码
[2]如何模拟进程阻塞:操作系统实验之银行家算法模拟_这儿有个bug-CSDN博客