#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
//系统当前可用资源和正在生成中的进程序列
typedef struct _ResAndP {
int iAvailableRa;//系统当前资源A总数量
int iAvailableRb;//系统当前资源B总数量
int iAvailableRc;//系统当前资源C总数量
int iPOrder[5];//当前进程序列,最多5个
int iPCount; //进程队列中进程个数
}ResAndProcess;
//一个进程资源状态结构体
typedef struct _ResOfP {
int iMaxRa;//进程需要A资源的最大数量
int iMaxRb;//进程需要B资源的最大数量
int iMaxRc;//进程需要C资源的最大数量
int iAllocRa;//进程已分配的A资源数量
int iAllocRb;//进程已分配的B资源数量
int iAllocRc;//进程已分配的C资源数量
int iNeedRa;//进程还需要的A资源数量
int iNeedRb;//进程还需要的B资源数量
int iNeedRc;//进程还需要的C资源数量
}ResOfProcess;
ResAndProcess StartResAndP;
ResOfProcess AllResOfP[5];
//链表节点结构体,保存一个安全序列
typedef struct POrder {
int iPOrder[5];//安全的进程序列
struct POrder* next;//下个节点指针
}POrderNode;
POrderNode* HeadOfPOrder;//序列链表的头指针
//当前字符串转换到整数数组[5]
void LineToInts(char* lbuf, int* iArray, int iCount)
{
char StrIntBuf[10];//将字符串转为整数的缓冲区
int i, j, iStrStart, iStrEnd, iStrLen, iProIndex;
//17,5,20
iStrLen = strlen(lbuf);
i = 0;
iStrEnd = 0;
iStrStart = 0;
for (j = 0; j < iCount; j++)
{
memset(StrIntBuf, 0, 10);
for (; (i < iStrLen) && (lbuf[i] != ','); i++);
iStrEnd = i;
memcpy(StrIntBuf, lbuf + iStrStart, iStrEnd - iStrStart);
iArray[j] = atoi(StrIntBuf);
i++;
iStrStart = i;
}
}
//从banker.dat文件读入数据
int ReadBankData()
{
/*
FILE * fp=NULL;
int fd = -1,i;
ssize_t size = -1;
char Linebuf[100]; /*存放数据的缓冲区*/
/*
char *pchar=NULL;
char filename[] = "banker.dat";
int Numbers[6];//用于保存字符串转换的临时整数数组
fp=fopen(filename,"r");
if(fp==NULL)
{//文件打开失败
printf("Open file %s failure,fd:%d\n",filename,fd);
return;
}
memset((void *)Linebuf,0,(size_t)100);//清空数组
pchar=fgets(Linebuf,100,fp);
LineToInts(Linebuf,Numbers,3);
StartResAndP.iAvailableRa=Numbers[0];
StartResAndP.iAvailableRb=Numbers[1];
StartResAndP.iAvailableRc=Numbers[2];
for(i=0;i<5;i++)
{
memset((void *)Linebuf,0,(size_t)100);//清空数组
pchar=fgets(Linebuf,100,fp);
LineToInts(Linebuf,Numbers,6);
AllResOfP[i].iMaxRa=Numbers[0];
AllResOfP[i].iMaxRb=Numbers[1];
AllResOfP[i].iMaxRc=Numbers[2];
AllResOfP[i].iAllocRa=Numbers[3];
AllResOfP[i].iAllocRb=Numbers[4];
AllResOfP[i].iAllocRc=Numbers[5];
AllResOfP[i].iNeedRa=Numbers[0]-Numbers[3];
AllResOfP[i].iNeedRb=Numbers[1]-Numbers[4];
AllResOfP[i].iNeedRc=Numbers[2]-Numbers[5];
}
//关闭文件
fclose(fp);
*/
/* 运行矩阵:
Pi Maxa,Maxb,Maxc,Alloca,Allocb,Allocc,Needa,Needb,Needc,Avaia,Avaib,Avaic
0 5,5,9, 2,1,2, 3,4,7, 1,5,2,
1 5,3,6, 4,0,2, 1,3,4,
2 4,0,11, 4,0,5, 0,0,6
3 4,2,5, 2,0,4, 2,2,1
4 4,2,4, 3,1,4, 1,1,0
*/
/*
1,5,2,
5,5,9,2,1,2,
5,3,6,4,0,2,
4,0,11,4,0,5,
4,2,5,2,0,4,
4,2,4,3,1,4,
*/
StartResAndP.iAvailableRa = 1;
StartResAndP.iAvailableRb = 5;
StartResAndP.iAvailableRc = 2;
int i = 0;
AllResOfP[i].iMaxRa = 5;
AllResOfP[i].iMaxRb = 5;
AllResOfP[i].iMaxRc = 9;
AllResOfP[i].iAllocRa = 2;
AllResOfP[i].iAllocRb = 1;
AllResOfP[i].iAllocRc = 2;
AllResOfP[i].iNeedRa = AllResOfP[i].iMaxRa - AllResOfP[i].iAllocRa;
AllResOfP[i].iNeedRb = AllResOfP[i].iMaxRb - AllResOfP[i].iAllocRb;
AllResOfP[i].iNeedRc = AllResOfP[i].iMaxRc - AllResOfP[i].iAllocRc;
i = 1;
AllResOfP[i].iMaxRa = 5;
AllResOfP[i].iMaxRb = 3;
AllResOfP[i].iMaxRc = 6;
AllResOfP[i].iAllocRa = 4;
AllResOfP[i].iAllocRb = 0;
AllResOfP[i].iAllocRc = 2;
AllResOfP[i].iNeedRa = AllResOfP[i].iMaxRa - AllResOfP[i].iAllocRa;
AllResOfP[i].iNeedRb = AllResOfP[i].iMaxRb - AllResOfP[i].iAllocRb;
AllResOfP[i].iNeedRc = AllResOfP[i].iMaxRc - AllResOfP[i].iAllocRc;
i = 2;
AllResOfP[i].iMaxRa = 4;
AllResOfP[i].iMaxRb = 0;
AllResOfP[i].iMaxRc = 11;
AllResOfP[i].iAllocRa = 4;
AllResOfP[i].iAllocRb = 0;
AllResOfP[i].iAllocRc = 5;
AllResOfP[i].iNeedRa = AllResOfP[i].iMaxRa - AllResOfP[i].iAllocRa;
AllResOfP[i].iNeedRb = AllResOfP[i].iMaxRb - AllResOfP[i].iAllocRb;
AllResOfP[i].iNeedRc = AllResOfP[i].iMaxRc - AllResOfP[i].iAllocRc;
i = 3;
AllResOfP[i].iMaxRa = 4;
AllResOfP[i].iMaxRb = 2;
AllResOfP[i].iMaxRc = 5;
AllResOfP[i].iAllocRa = 2;
AllResOfP[i].iAllocRb = 0;
AllResOfP[i].iAllocRc = 4;
AllResOfP[i].iNeedRa = AllResOfP[i].iMaxRa - AllResOfP[i].iAllocRa;
AllResOfP[i].iNeedRb = AllResOfP[i].iMaxRb - AllResOfP[i].iAllocRb;
AllResOfP[i].iNeedRc = AllResOfP[i].iMaxRc - AllResOfP[i].iAllocRc;
i = 4;
AllResOfP[i].iMaxRa = 4;
AllResOfP[i].iMaxRb = 2;
AllResOfP[i].iMaxRc = 4;
AllResOfP[i].iAllocRa = 3;
AllResOfP[i].iAllocRb = 1;
AllResOfP[i].iAllocRc = 4;
AllResOfP[i].iNeedRa = AllResOfP[i].iMaxRa - AllResOfP[i].iAllocRa;
AllResOfP[i].iNeedRb = AllResOfP[i].iMaxRb - AllResOfP[i].iAllocRb;
AllResOfP[i].iNeedRc = AllResOfP[i].iMaxRc - AllResOfP[i].iAllocRc;
return 1;
}
//检查安全序列集回安全序列个数
int getSecurePCount()
{
int SecuPCount = 0;
int i = 0;
POrderNode* curNode = NULL;
//释放所有节点
while (HeadOfPOrder != NULL)
{
SecuPCount++;//为了方便在线检测,这里仅获得安全序列个数
curNode = HeadOfPOrder;
//根据需要也可以输出安全序列,去掉注释符号即可输出安全序列 //printf("安全序列是:%d,%d,%d,%d,%d.\n",curNode->iPOrder[0],curNode->iPOrder[1],curNode->iPOrder[2],curNode->iPOrder[3],curNode->iPOrder[4]);
HeadOfPOrder = HeadOfPOrder->next;
free((void*)curNode);
}
return SecuPCount;
}
//检查当前资源条件,序号为iPIndex的进程资源需求是否可以分配资源
int CheckResource(ResAndProcess* aRAndP, int iPIndex)
{
int iResult = 0;
//iPIndex为进程序列中的序号
//Available>=Need,则返回值1
//给出iPIndex编号的进程是否可以分配资源的判断逻辑
/* begin ******************************************************** */
if (aRAndP->iAvailableRa >= AllResOfP[iPIndex].iNeedRa &&
aRAndP->iAvailableRb >= AllResOfP[iPIndex].iNeedRb &&
aRAndP->iAvailableRc >= AllResOfP[iPIndex].iNeedRc) {
iResult = 1;
}
/* end ************************************************************** */
//如果不满足要求会返回0值
return iResult;
}
//银行家安全算法递归算法,得到所有安全序列,
void BankerSecurity(ResAndProcess* curRAndP)
{
int i = 0, j = 0;
int iDxDontInQue = 1;
int iNewPOrder = 0;
ResAndProcess* tmpP;
//请在begin end语句间补判断语句
//判断逻辑是当前生成的进程序列已达到满序列,表示全部进程可以执行完成
/* begin *******************程序代码一行******************************* */
if (curRAndP -> iPCount == 5)
/* end ************************************************************** */
{
//将当前安全序列添加到链表中
//创建一个安全序列的节点指针
//将一个安全的进程序列拷贝到添加到链表中添加到链表中
//注意不同平台的int字节数不同,要使用sizeof(int)确定长度
//因curRAndP节点会被回收,所以要将值拷贝到oneNode节点
//将当前安全序列添加到链表头。
//请根据上述提示补上相应功能的代码
/* begin *******************程序代码四行******************************* */
POrderNode* oneNode;
oneNode = (POrderNode*)malloc(sizeof(POrderNode));
for (int i = 0; i < 5; i++) {
oneNode->iPOrder[i] = curRAndP->iPOrder[i];
}
oneNode->next = HeadOfPOrder;
HeadOfPOrder = oneNode;
/* end ************************************************************** */
//递归到此结束,开始回退
return;
}
else {
//取下面可能的进程编号继续下层递归
for (i = 0; i < 5; i++)
{
iDxDontInQue = 1;
//检查当前进程序号是否在队列中
for (j = 0; j < curRAndP->iPCount; j++)
{
if (i == curRAndP->iPOrder[j])
{//找到下标则表示i在当前队列中
iDxDontInQue = 0;
break;
}
}
//请编写逻辑,实现递归生成安全序列的代码,注意内存的申请和回收
/* begin *******************程序代码约十二行******************************* */
if (iDxDontInQue == 1 && CheckResource(curRAndP, i)) {
ResAndProcess* tmpP = (ResAndProcess*)malloc(sizeof(ResAndProcess));
for (int k = 0; k < 5; k++) {
tmpP->iPOrder[k] = curRAndP->iPOrder[k];
}
tmpP->iAvailableRa = curRAndP->iAvailableRa - AllResOfP[i].iNeedRa + AllResOfP[i].iMaxRa;
tmpP->iAvailableRb = curRAndP->iAvailableRb - AllResOfP[i].iNeedRb + AllResOfP[i].iMaxRb;
tmpP->iAvailableRc = curRAndP->iAvailableRc - AllResOfP[i].iNeedRc + AllResOfP[i].iMaxRc;
tmpP->iPCount = curRAndP->iPCount + 1;
tmpP->iPOrder[tmpP->iPCount - 1] = i;
BankerSecurity(tmpP);
free(tmpP);
}
/* end ************************************************************** */
}
}
}
int main(void)
{
int iSqcount = 0;
//初始化数据,安全序列链表初始为空
HeadOfPOrder = NULL;
//读入文件数据
if (ReadBankData())
{
ResAndProcess* initResAndPro = (ResAndProcess*)malloc(sizeof(ResAndProcess));
//请在begin end语句间补全程序语句实现对initResAndPro赋初值操作
/* begin *******************程序代码约四行******************************* */
initResAndPro->iAvailableRa = StartResAndP.iAvailableRa;
initResAndPro->iAvailableRb = StartResAndP.iAvailableRb;
initResAndPro->iAvailableRc = StartResAndP.iAvailableRc;
initResAndPro->iPCount = 0;
/* end ************************************************************** */
//启动银行家算法
BankerSecurity(initResAndPro);
//得到安全序列的个数(或者输出全部安全序列)
iSqcount = getSecurePCount();
if (iSqcount > 0)
{
printf("%d", iSqcount);
}
else {
printf("未找到安全序列。");
}
}
else {
//文件数据读取失败则输出0
printf("banker.dat文件读取失败。");
};
return 0;
}