操作系统--银行家算法

操作系统--银行家算法

  • 银行家算法的基本思想
  • 银行家算法代码的实现
  • 银行家完整代码如下

银行家算法的基本思想

在资源分配前,判断系统是否处于安全状态,如处于安全状态则把资源分配给申请进程,如处于不安全状态则令申请资源的进程堵塞,不响应其资源申请。银行家算法的核心理念就是把资源分配给那些最容易执行完成的进程,保证系统中各进程都能正常完成。

银行家算法代码的实现

  1. 定义全局变量 ,方便函数的输入。再定义函数:int Safe(),void print(),advice() Safe是安全性算法函数,是核心代码。print是打印函数,打印出每一次申请后的结果。advice是建议函数,能够在你申请进程资源的时候建议你该怎么申请才不会死锁。个人认为最得意的函数就是建议函数advice
#include <stdio.h>
#include <stdlib.h>
#define N 100
#define M 50
int Available[N]; //可利用资源数组
int Max[M][N]; //最大需求矩阵
int Allocation[M][N]; //分配矩阵
int Need[M][N]; //需求矩阵
int Request[M][N]; //M 个进程还需要 N 类资源的资源量
int Finish[M];      //在安全检测函数里标记进程是否被使用过
int p[M];           //安全运行进程的顺序记录,会用在advice函数里
int Adv;      //Adv提示你该输入哪个进程。
int m,n; //m 个进程,n 类资源

int Safe();

void print();

void advice();
  1. int Save()函数的实现原理 Save函数是一个检测型函数,所以运行函数时不能影响到不该影响的全局变量:int Available[],所以将Available[]赋值给 Work[],用Work[]代替Available[]去检测申请的资源是否安全。而int Finish[]是标记变量,标记进程是否通过了安全性检测,如果通过了标记为1,否则为0。;
int Safe()
{
    int i,j,l=0;
    int Work[100];      //可利用资源数组
    for (i=0;i<n;i++)
        Work[i]=Available[i];
    for (i=0;i<m;i++)
        Finish[i]=0;
    for (i=0;i<m;i++)
    {
        if (Finish[i]==1)
            continue;
        else
        {
            for (j=0;j<n;j++)       //如果该进程中所有需要的资源数都小于可提供的资源数,则不会触发break。
            {
                if (Need[i][j]>Work[j])
                    break;
            }
            if (j==n)       //表示该进程安全
            {
                Finish[i]=1;
                for(int k=0;k<n;k++)
                    Work[k]+=Allocation[i][k];      //将进程所占有的资源释放回计算机
                p[l++]=i;       //记录进程被释放的顺序,用于advice函数上。
               i=-1;        //这步很关键
            }
            else continue;
        }
        if (l==m)
        {
            printf("系统是安全的\n");
                printf("系统安全序列是:\n");
            for (i=0;i<l;i++)
            {
                printf("%d",p[i]);
                if (i!=l-1)
                    printf("-->");
            }
            printf("\n");
            return 1;
        }
    }
    return 0;
}

解释一下为什么要 i=-1,那就先举个栗子吧!!
假设进程数为3,资源数为2。可利用资源Available[ ]分别为 1、2。各个进程还需要的资源Need[ ][ ]分别为P0:3、4。 P1:2、3。 P2:1、2。为了例子能举简单些,让Need[ ][ ]等于Allocation[ ][ ]
Available[ ]

资源类型 资源数
A 1
B 2

Need [ ]

进程类型 资源类型A 资源类型B
P0 3 4
P1 2 3
P2 1 2

如果没有i=-1会怎么运行?
if (Need[i][j]>Work[j]) break;这条语句只会在P2时不执行break,但执行for语句时i==m,跳出了for循环。会检测出不能安全运行的错误。
本来可以P2–>P1–>p0安全运行,但因为少了i=-1。产生了逻辑错误

  1. void advice()函数的实现原理
    Adv是一个全局变量,用来存放推荐的进程号。我们先将数组P[ ]的第一个进程号赋值给Adv,如果该进程号对应的所需资源数Need不为0,则推荐该进程号,否则选择下一个进程号。
void advice()
{
    int i,j=0;
    int count=0;
    Adv=p[count];      //先选定P[0]为第一个建议输出的进程
    for (i=0;i<m;i++)
    {
        if (count!=i)       //当count不等于i时,表示找到了推荐的进程。
            break;
        for (j=0;j<n;j++)       //如果这个进程需要资源,那么就推荐这个进程
            if (Need[Adv][j]!=0)
                break;
        if (j==n)       //如果上一个进程不需要资源就指向下一个P[]数组里的进程号
        {
            count++;
            Adv=p[count];
        }
    }
}

银行家完整代码如下

#include <stdio.h>
#include <stdlib.h>
#define N 100
#define M 50
int Available[N]; //可利用资源数组
int Max[M][N]; //最大需求矩阵
int Allocation[M][N]; //分配矩阵
int Need[M][N]; //需求矩阵
int Request[M][N]; //M 个进程还需要 N 类资源的资源量
int Finish[M];      //在安全检测函数里标记进程是否被使用过
int p[M];           //安全运行进程的顺序记录
int Adv;      //Adv提示你该输入哪个进程。
int m,n; //m 个进程,n 类资源

int Safe();

void print();

void advice();

int main()
{
    int mi;
    int i,j;
  //  int Max[N][M],Available[M],Allocation[N][M],Need[N][M];
    printf("请输入进程数:");
    scanf("%d",&m);
    printf("请输入资源数:");
    scanf("%d",&n);
    printf("请输入最大需求矩阵Max:\n");
    printf("\tMax\n\t");
    for (j=0;j<n;j++)
        printf("%c\t",'A'+j);
    printf("\n");
    for (i=0;i<m;i++)
    {
        printf("P%d\t",i);
        for (j=0;j<n;j++)
        {
            scanf("%d",&Max[i][j]);
        }
    }

    printf("请输入分配矩阵Allocation:\n");
    printf("\tAllocation\n\t");
    for (j=0;j<n;j++)
        printf("%c\t",'A'+j);
    printf("\n");
    for (i=0;i<m;i++)
    {printf("P%d\t",i);
        for (j=0;j<n;j++)
        {
            scanf("%d",&Allocation[i][j]);
        }
    }

    printf("请输入分配矩阵Need:\n");
    printf("\tNeed\n\t");
    for (j=0;j<n;j++)
        printf("%c\t",'A'+j);
    printf("\n");
    for (i=0;i<m;i++)
    {   printf("P%d\t",i);
        for (j=0;j<n;j++)
        {
            Need[i][j]=Max[i][j]-Allocation[i][j];
            printf("%d",Need[i][j]);
            printf("\t");
        }
        printf("\n");
    }
    printf("请输入分配矩阵Available:\n");
    printf("\tAvailable\n\t");
    for (j=0;j<n;j++)
        printf("%c\t",'A'+j);
    printf("\n\t");
    for (j=0;j<n;j++)
    {
        scanf("%d",&Available[j]);
    }
    printf("\n");

    print();
    Safe();
    while (1)
    {
        advice();
        printf("输入要申请的资源的进程号:(1,2,3...)\t");
        printf("(建议你输入%d)\n",Adv);
        scanf("%d",&mi);
        printf("你实际输入的资源的进程号:%d\n",mi);
        printf("输入进程所请求的各个资源的数量\t");
        printf("建议你输入:");
        for (j=0;j<n;j++)
            printf("%d\t",Need[mi][j]);
        printf("\n");
        printf("你实际输入的各个资源的数量:");
        for (i=0;i<n;i++)
            scanf("%d",&Request[mi][i]);
        printf("\n");
        for (i=0;i<n;i++)
        {
            if (Request[mi][i]>Need[mi][i])
            {
                printf("所请求资源数超过进程的需求量\n");
                return 0;
            }
            if (Request[mi][i]>Available[i])
            {
                printf("所请求资源数超过系统所有的资源数!\n");
                return 0;
            }
        }
        for (i=0;i<n;i++)
        {
            Available[i]-=Request[mi][i];
            Allocation[mi][i]+=Request[mi][i];
            Need[mi][i]-=Request[mi][i];
        }
        if (Safe())
        {
            printf("同意分配请求\n");
            for (i=0;i<n;i++)
                if (Need[mi][i]!=0)
                    break;
            if(i==n)
            {
                for (i=0;i<n;i++)
                {
                    Available[i]=Available[i]+Request[mi][i]+Allocation[mi][i];
                    Allocation[mi][i]=0;
                }
            }
            print();
        }
        else
        {
            printf("SORRY你的请求被拒绝\n");
            for (i=0;i<n;i++)
            {
                Available[i]+=Request[mi][i];
                Allocation[mi][i]-=Request[mi][i];
                Need[mi][i]+=Request[mi][i];
            }
        }
        for (i=0;i<m;i++)
            Finish[i]=0;
        char Flag; //标志位
        printf("是否再次请求分配?是请按 Y/y,否请按 N/n");
        while (1)
        {
            scanf("%c",&Flag);
            if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n')
                break;
            else
            {
                printf("请按要求重新输入:\n");
                continue;
            }
        }
        if (Flag=='Y'||Flag=='y')
            continue;
        else break;
    }
    return 0;
}

void advice()
{
    int i,j=0;
    int count=0;
    Adv=p[count];      //先选定P[0]为第一个建议输出的进程
    for (i=0;i<m;i++)
    {
        if (count!=i)       //当count不等于i时,表示找到了推荐的进程。
            break;
        for (j=0;j<n;j++)       //如果这个进程需要资源,那么就推荐这个进程
            if (Need[Adv][j]!=0)
                break;
        if (j==n)       //如果上一个进程不需要资源就指向下一个P[]数组里的进程号
        {
            count++;
            Adv=p[count];
        }
    }
}

int Safe()
{
    int i,j,l=0;
    int Work[100];      //可利用资源数组
    for (i=0;i<n;i++)
        Work[i]=Available[i];
    for (i=0;i<m;i++)
        Finish[i]=0;
    for (i=0;i<m;i++)
    {
        if (Finish[i]==1)
            continue;
        else
        {
            for (j=0;j<n;j++)       //如果该进程中所有需要的资源数都小于可提供的资源数,则不会触发break。
            {
                if (Need[i][j]>Work[j])
                    break;
            }
            if (j==n)       //表示该进程安全
            {
                Finish[i]=1;
                for(int k=0;k<n;k++)
                    Work[k]+=Allocation[i][k];      //将进程所占有的资源释放回计算机
                p[l++]=i;       //记录进程被释放的顺序,用于advice函数上。
               i=-1;        //这步很关键
            }
            else continue;
        }
        if (l==m)
        {
            printf("系统是安全的\n");
                printf("系统安全序列是:\n");
            for (i=0;i<l;i++)
            {
                printf("%d",p[i]);
                if (i!=l-1)
                    printf("-->");
            }
            printf("\n");
            return 1;
        }
    }
    return 0;
}

void print()
{
    int i,j,flag=0;
    printf("\t\tMax\t\t\tAllocation\t\tNeed\n");
    for (i=0;i<3;i++)
        for (j=0;j<n;j++)
            printf("\t%c",'A'+j);
    printf("\n");
    for (i=0;i<m;i++)
    {
        printf("P%d\t",i);
        for (j=0;j<n;j++)
            printf("%d\t",Max[i][j]);
        for (j=0;j<n;j++)
            printf("%d\t",Allocation[i][j]);
        for (j=0;j<n;j++)
            printf("%d\t",Need[i][j]);
        printf("\n");
    }
    printf("\tAvailable\n");
    for (j=0;j<n;j++)
        printf("\t%c",'A'+j);
    printf("\n");
    for (j=0;j<n;j++)
        printf("\t%d",Available[j]);
    printf("\n");
}

这是我的第一篇博客,如有不足,请各位大佬不吝赐教。谢谢!

你可能感兴趣的:(python闲写,操作系统--银行家算法)