本关任务:编写银行家算法程序找出进程执行的安全序列。

#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;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值