银行家算法

引言

我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.

数据结构

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]

实现

目的:避免死锁的产生。

算法思想:

 1、假分配检测:Request < Need
              Request < Available
 2、安全序列检测算法

举例说明:

某系统有R1,R2,R3共3中资源,在T0时刻P0,P1,P2,P3和P4这5个进程对资源的占用和需求情况如下表1,此时系统的可用资源向量为(3,3,2)。试问:

1、T0时刻系统是否存在安全序列?

2、P1请求资源:P1发出请求向量Request(1,0,2),系统是否接受该请求?请使用银行家算法检查

3、P4请求资源:P4发出请求向量Request(3,3,0),系统按银行家算法检查.

4、P0请求资源:P0发出请求向量Request(0,2,0),系统按银行家算法检查.

      表1 T0时刻的资源分配表


  1、T0时刻系统是否存在安全序列?

解析: 
Available > Need1 —-> 可用资源分配给P1,直到P1进程执行完成,然后Available = Available + Allocation1 = (5,3,2)
Available > Need3 —–> 可用资源分配给P3,直到P3进程执行完成,然后Available = Available + Allocation3 = (7,4,3)
 Available> Need4…..

得到安全序列为:P1,P3,P4,P0,P2

  2、P1请求资源:P1发出请求向量Request(1,0,2),系统是否接受该请求?请使用银行家算法检查

解析
第一步(假分配检查):把Request分配给P1,必须满足Request要小于Available,Request要小于Need。
Request(1,0,2)< Available(3,3,2)
Request(1,0,2)< Need(1,2,2)
因为满足第一步检查,进入第二层检查(安全序列检查)。

第二步(安全序列检查):建立安全性检查表

 
 如果 Work > Need ,那么执行Work+Allocation,得到:
 

找到 Need<work 的进程,如果没有找到这样的进程而进程集合没有执行,则算法返回,得到不存在安全序列结果,否则继续执行该算法。

这里我们找到了P3进程。修改安全序列检查表:

  这样一直执行到所有的进程到完成,以完成该安全序列检查表:


这样就找到了整个安全序列为:P1,P3,P4,P0,P2

  3、4小问也是同样的解题过程。这里不赘述…

程序流程图:

1.初始化算法流程图:

2.银行家算法流程图:

3.安全性算法流程图:

实现细节

1.设进程i提出请求Request[n],则银行家算法按如下规则进行判断。
(1)如果Request[n]>Need[i,n],则报错返回。
(2)如果Request[n]>Available,则进程i进入等待资源状态,返回。
(3)假设进程i的申请已获批准,于是修改系统状态:
Available=Available-Request
Allocation=Allocation+Request
Need=Need-Request
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
2.安全性检查
(1)设置两个工作向量Work=Available;Finish =False
(2)从进程集合中找到一个满足下述条件的进程,
Finish =False
Need<=Work
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+Allocation
Finish=True
GO TO 2
(4)如所有的进程Finish =true,则表示安全;否则系统不安全。

C++代码实现

#include <iostream>  
using namespace std;
#define MAXPROCESS 50                        /*最大进程数*/
#define MAXRESOURCE 100                        /*最大资源数*/
int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*进程需要资源数*/
bool FINISH[MAXPROCESS];                        /*系统是否有足够的资源分配*/
int p[MAXPROCESS];                             /*记录序列*/
int m, n;                                    /*m个进程,n个资源*/
void Init();
bool Safe();
void Bank();
void showdata(int, int);
int main()
{
    Init();
    Safe();
    Bank();
}
void Init()                /*初始化算法*/
{
    int i, j;
    cout << "请输入进程的数目:";
    cin >> m;
    cout << "请输入资源的种类:";
    cin >> n;
    cout << "请输入每个进程最多所需的各资源数,按照" << m << "x" << n << "矩 阵输入" << endl;
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            cin >> MAX[i][j];
    cout << "请输入每个进程已分配的各资源数,也按照" << m << "x" << n << "矩 阵输入" << endl;
    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 << "个资源数 错误,请重新输入:" << endl;
                j--;
                continue;
            }
        }
    }
    cout << "请输入各个资源现有的数目:" << endl;
    for (i = 0; i < n; i++)
    {
        cin >> AVAILABLE[i];
    }
}
void Bank()                /*银行家算法*/
{
    int i, cusneed, flag = 0;
    char again;
    while (1)
    {
        showdata(n, m);
        cout << endl;
    input:
        cout << "请输入要申请资源的进程号(注:第1个进程号为0,依次类推)" << endl;
        cin >> cusneed;
        if (cusneed >=m)
        {
            cout << "没有该进程,请重新输入" << endl;
            goto input;
        }
        cout << "请输入进程所请求的各资源的数量" << endl;
        for (i = 0; i < n; i++)
        {
            cin >> REQUEST[cusneed][i];
        }
        for (i = 0; i < n; i++)
        {
            if (REQUEST[cusneed][i] > NEED[cusneed][i])//如果用户选择的线程的第i个资源请求数>该线程该资源所需的数量
            {
                cout << "您输入的请求数超过进程的需求量!请重新输入!" << endl;
                goto input;
            }
            if (REQUEST[cusneed][i] > AVAILABLE[i])//如果用户选择的线程的第i个资源请求数>系统现有的第i个资源的数量
            {
                cout << "您输入的请求数超过系统有的资源数!请重新输入!" << endl;
                goto input;
            }
        }
        for (i = 0; i < n; i++)//如果请求合理,那么下面
        {
            AVAILABLE[i] -= REQUEST[cusneed][i];//系统可用资源减去申请了的
            ALLOCATION[cusneed][i] += REQUEST[cusneed][i];//线程被分配的资源加上已申请了的
            NEED[cusneed][i] -= REQUEST[cusneed][i];//线程还需要的资源减去已申请得到的
        }
        if (Safe())//AVAILABLE  ALLOCATION  NEED变动之后,是否会导致不安全
        {
            cout << "同意分配请求!" << endl;
        }
        else
        {
            cout << "您的请求被拒绝!" << endl;
            for (i = 0; i < n; i++)
            {
                AVAILABLE[i] += REQUEST[cusneed][i];
                ALLOCATION[cusneed][i] -= REQUEST[cusneed][i];
                NEED[cusneed][i] += REQUEST[cusneed][i];
            }
        }
        for (i = 0; i < n; i++)
        {
            if (NEED[cusneed][i] <= 0)
            {
                flag++;
            }
        }
        if (flag == n)//如果该进程各资源都已满足条件,则释放资源
        {
            for (i = 0; i < n; i++)
            {
                AVAILABLE[i] += ALLOCATION[cusneed][i];
                ALLOCATION[cusneed][i] = 0;
                NEED[cusneed][i] = 0;
            }
            cout << "线程" << cusneed << " 占有的资源被释放!" << endl;
            flag = 0;
        }
        for (i = 0; i < m; i++)//分配好了以后将进程的标识FINISH改成false
        {
            FINISH[i] = false;
        }
        cout << "您还想再次请求分配吗?是请按y/Y,否请按其它键" << endl;
        cin >> again;
        if (again == 'y' || again == 'Y')
        {
            continue;
        }
        break;
    }
}
bool Safe()                                    /*安全性算法*/
{
    int i, j, k, l =0;
    int Work[MAXRESOURCE];                    /*工作数组*/
    for (i = 0; i < n; i++)
        Work[i] = AVAILABLE[i];
    for (i = 0; i < m; i++)
    {
        FINISH[i] = false;//FINISH记录每个进程是否安全
    }
    while (l<m)//正常的话,共执行m次
    {
        int init_index = l;
        for (i = 0; i < m; i++)
        {
            if (FINISH[i] == true)
            {
                continue;
            }
            for (j = 0; j < n; j++)//循环查找第i个进程需要的各个资源数 是否 超过系统现有的对应的资源数
            {
                if (NEED[i][j] > Work[j])//第i个进程需要的第j个资源数 > 系统现有的第j个资源数
                {
                    break;
                }
            }
            if (j == n)//如果第i个进程所需的各个资源数都没有超过系统现有的对应资源数
            {
                FINISH[i] = true;//给该进程的FINISH标记为true
                for (k = 0; k < n; k++)
                {
                    Work[k] += ALLOCATION[i][k];//将Work赋值为 第i个进程各个已分配资源数+系统现有的对应资源数(因为当改进程全部资源数都满足时线程结束并将资源返还给系统)
                }
                p[l++] = i;//记录进程号

            }
            else//如果超过继续循环下一个进程
            {
                continue;
            }
        }
        if (l==init_index)
        {
            cout << "系统是不安全的" << endl;
            return false;
        }
    }//for循环

        cout << "系统是安全的" << endl;
        cout << "安全序列:" << endl;
        for (i = 0; i < l; i++)//改了146行的i值,显示资源分配给进程的顺序
        {
            cout << p[i];
            if (i != l - 1)
            {
                cout << "-->";
            }
        }
        cout << "" << endl;
        return true;


}

void showdata(int n, int m)   //显示
{
    int i, j;
    cout << endl;
    cout << "-------------------------------------------------------------" << endl;
    cout << "系统可用的资源数为:    ";
    for (j = 0; j < n; j++)
        cout << "    " << AVAILABLE[j];
    cout << endl;
    cout << "各进程还需要的资源量:" << endl;
    for (i = 0; i < m; i++)
    {
        cout << "    进程" << i << ":";

        for (j = 0; j < n; j++)
            cout << "     " << NEED[i][j];
        cout << endl;
    }

    cout << endl;
    cout << "各进程已经得到的资源量:    " << endl << endl;

    for (i = 0; i < m; i++)
    {
        cout << "    进程" << i << ":";

        for (j = 0; j < n; j++)
            cout << "     " << ALLOCATION[i][j];
        cout << endl;
    }
    cout << endl;
} 

参考文献

1.http://blog.csdn.net/yaopeng_2005/article/details/6935235#cpp
2.http://blog.csdn.net/pi9nc/article/details/12401491

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值