一、实验内容

银行家算法的实现。

二、实验目的

银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。通过编写一个模拟动态资源分配的银行家算法程序,帮助学生进一步深入理解死锁、产生死锁的必要条件、安全状态等重要概念,并掌握避免死锁的具体实施方法。

三、实验原理

3.1、银行家算法中的数据结构 

1)可利用资源向量Available

是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。 

2)最大需求矩阵Max

这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵Allocation

这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。

4)需求矩阵Need。

这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。  

Need[i,j]=Max[i,j]-Allocation[i,j] 

3.2、银行家算法

设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。

(2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。 

(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:

Available[j]=Available[j]-Requesti[j];

Allocation[i,j]=Allocation[i,j]+Requesti[j];  

Need[i,j]=Need[i,j]-Requesti[j];

系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

3.3、安全性算法

1)设置两个向量:

工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available;

工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。 

2)从进程集合中找到一个能满足下述条件的进程:         

Finish[i]=false;

Need[i,j]≤Work[j];若找到,执行 (3),否则,执行 (4)

3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:

Work[j]=Work[i]+Allocation[i,j];

Finish[i]=true;

go to step 2;

4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态

四、算法流程图

mysql银行家算法 银行家算法实现_银行家算法

五、源程序及注释

#include <iostream>

using namespace std;

 

//全局变量定义

int Available[100]; //可利用资源数组

int Max[50][100];   //最大需求矩阵

int Allocation[50][100];  //分配矩阵

int Need[50][100];        //需求矩阵

int Request[50][100];     //M个进程还需要N类资源的资源量

int Finish[50];

int p[50];

int m,n;   //M个进程,N类资源

 

//安全性算法

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++)

            {

                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;

                i=-1;

            }

            else continue;

        }

        if (l==m)

        {

            cout<<"系统是安全的"<<'\n';

            cout<<"系统安全序列是:\n";

            for (i=0;i<l;i++)

            {

                cout<<p[i];

                if (i!=l-1)

                    cout<<"-->";

            }

            cout<<'\n';

            return 1;

        }

    }

}

/

//银行家算法

int main()

{

    int i,j,mi;

    cout<<"输入进程的数目:\n";

    cin>>m;

    cout<<"输入资源的种类:\n";

    cin>>n;

    cout<<"输入每个进程最多所需的各类资源数,按照"<<m<<"x"<<n<<"矩阵输入\n";

    for (i=0;i<m;i++)

        for(j=0;j<n;j++)

            cin>>Max[i][j];

    cout<<"输入每个进程已经分配的各类资源数,按照"<<m<<"x"<<n<<"矩阵输入\n";

    for (i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        {

            cin>>Allocation[i][j];

            Need[i][j]=Max[i][j]-Allocation[i][j];

            if (Need[i][j]<0)

            {

                cout<<"你输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源错误,请重新输入:\n";

                j--;

                continue;

            }

        }

    }

    cout<<"请输入各个资源现有的数目:\n";

    for (i=0;i<n;i++)

    cin>>Available[i];

    Safe();

    while (1)

    {

        cout<<"输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";

        cin>>mi;

        cout<<"输入进程所请求的各个资源的数量\n";

        for (i=0;i<n;i++)

        cin>>Request[mi][i];

        for (i=0;i<n;i++)

        {

 

            if (Request[mi][i]>Need[mi][i])

            {

                cout<<"所请求资源数超过进程的需求量!\n";

                return 0;

            }

            if (Request[mi][i]>Available[i])

            {

                cout<<"所请求资源数超过系统所有的资源数!\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())

            cout<<"同意分配请求\n";

        else

        {

            cout<<"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;       //标志位

        cout<<"是否再次请求分配?是请按Y/y,否请按N/n";

        while (1)

        {

            cin>>Flag;

            if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n')

            break;

            else

            {

                cout<<"请按要求重新输入:\n";

                continue;

            }

        }

        if (Flag=='Y'||Flag=='y')

        continue;

        else break;

    }

}

 

六、打印的程序运行时初值和运行结果

mysql银行家算法 银行家算法实现_mysql银行家算法_02

七、实验小结

通过本次实验,对银行家算法有了更深刻而认识。并且认识到要验证原理,实践是最好的。对于算法的验证,首先一定要理论上清楚算法的原理,然后再去实际验证。

注意:

系统资源名称、系统资源数量、进程数量、各进程对资源的最大需求、各进程已申请到资源数等信息初始值不可以在程序中指定固定值,要在程序运行后人工输入。