/*-----------------------函数声明--------------------*/
int tryAdminister(int num);//试分配
void safeCheck(int num);   //安全性检查
void Print();              //状态输出
/*主函数(只需改变n、m和下面的初始数组便可形成新的进程量,资源量和状态)*/
int main()
{
    int i, j, num;
    int total[n][m]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
    int have[n][m]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
    int want[n][m]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
    for (i=0;i<n;i++)               //初始化进程资源分配状态
        for (j=0;j<m;j++)
        {
            P[i].flag = F;
            P[i].Max[j]=total[i][j];
            P[i].Allocation[j]=have[i][j];
            P[i].Need[j]=want[i][j];
        }
Print(); //状态输出
    while (scanf("%d",&num)!=EOF)
    {
        printf("输入进程%d对这三类资源的需求向量(用空格隔开):\n",num);
        scanf("%d %d %d",&P[num].Request[0],&P[num].Request[1],&P[num].Request[2]);
        if (tryAdminister(num)==T)
            safeCheck(num);
Recycle(); //资源回收
        if(backDos()==T)                    //所有进程完则返回操作系统
        return 0;
        Print();
    }
    return 0;
}
/*--------------------------------------------------------------------*/
/*----------------------------试分配函数-----------------------------*/
int tryAdminister(int num)                          //试分配
{
    int j;
    for (j=0;j<m;j++)
        if (P[num].Request[j]>P[num].Need[j])
        {
            printf("非法请求!\n\n");
            return F;
        }
        else if (P[num].Request[j]>Available[j])
        {
            printf("%d号资源不够,无法分配,进程%d等待。\n\n",j,num);
            return F;
        }
    for (j=0;j<m;j++)
    {
        Available[j] = Available[j] - P[num].Request[j];
        P[num].Allocation[j] = P[num].Allocation[j] + P[num].Request[j];
        P[num].Need[j] = P[num].Need[j] - P[num].Request[j];
    }
    return T;
}
/*-------------------------------安全性检查函数-------------------------------*/
void safeCheck(int num)
{
    int i,j;
    int l[n],k;            //安全序列
    for (j=0;j<m;j++)      //初始化工作向量
        Work[j]=Available[j];
    for (i=0;i<n;i++)      //初始化判断向量
        {
            Finish[i]=F;
            l[i]=0;
        }
    k=0;
    for (i=0;i<n;i++)
    {
        if (Finish[i]==F)
        {
            for (j=0;j<m;j++)
                if (P[i].Need[j]>Work[j])break;
            if (j==m)           //如果分配成功
            {
                for (j=0;j<m;j++)
                    Work[j]=Work[j]+P[i].Allocation[j];
                Finish[i]=T;
                l[k]=i;
                k++;            //安全序列
                i=-1;           //就重新查找下一个可分配成功的进程
            }
        }
    }
    for (i=0;i<n;i++)
        if (Finish[i]==F)
        {
            printf("分配不成功,系统将处于不安全状态.\n\n");
            for (j=0;j<m;j++)   //若分配不成功将进程num恢复到初始时刻状态
            {
                Available[j] = Available[j] + P[num].Request[j];
                P[num].Allocation[j] = P[num].Allocation[j] - P[num].Request[j];
                P[num].Need[j] = P[num].Need[j] + P[num].Request[j];
            }
            break;
        }
    if (i==n)
    {
        printf("系统安全,一个进程安全序列如下:\n");
        for (i=0;i<n;i++)
            if (i!=n-1)
                printf("P%d——>",l[i]);
            else
                printf("P%d\n\n",l[i]);
    }
}
/*------------------------------------状态输出-----------------------------*/
void Print()
{
    int i;
    printf("此时资源分配情况:\n");
    printf("********************************************************************\n");
    printf("\t最大需求\t已分配\t\t需要分配\t可用资源\n");
    for (i=0;i<n;i++)               //输出进程资源分配状态
    {
        printf("P%d\t%d %d %d\t\t",i,P[i].Max[0],P[i].Max[1],P[i].Max[2]);
        printf("%d %d %d\t\t",P[i].Allocation[0],P[i].Allocation[1],P[i].Allocation[2]);
www.751com.cn    for (i=0;i<n;i++)
    {
        for (j=0;j<m;j++)
            if (P[i].Need[j]!=0)break;
        if (j==m)
        {
            if (P[i].flag==F)
            {
                //若进程已得到所有资源并运行完则回收资源
                printf("进程P%d已运行完;\n\n",i);
                for (j=0;j<m;j++)
                    {
                        Available[j] = Available[j]+P[i].Allocation[j];
                        P[i].Allocation[j]=0;
                    }
                P[i].flag=T;
            }
        }
    }
}
/*-------------------------所有进程运行完就返回操作系统----------------------*/
int backDos()
{
    int i;
    for(i=0;i<n;i++)
    if(P[i].flag!=T)return F;
    printf("所有进程已经运行完,程序结束!\n");
    return T;
}