操作系统之银行家算法避免死锁

银行家算法避免死锁

要求:

  1. 完成程序数据结构的设计,数据的录入。
  2. 完成进程需求矩阵的输出,包括最大需求矩阵,尚需资源矩阵,可获得资源显示。
  3. 完成某进程请求资源试分配。
  4. 完成安全性检查。
  1. 1.         试探分配

当进程pi提出资源申请时,系统执行下列步骤:

(1)若Request[i][j]≤Need[i][j],转(2);

否则错误返回

(2)若Request[i][j]≤Available[j],

转(3);否则进程等待

(3)试探着把资源分配给进程Pi,则有:

Available[j]=Available[j]-Request[i][j];

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

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

  1. 2.         安全性检测算法:

n  借助于死锁的安全性测试算法来实现。

n  定义布尔型向量finish[k],k=1,..,n。检测死锁算法如下:

(1)Work= Available

(2)在剩余的进程集合中查每一个进程Pk,如果Claim[k,*]- Allocation [k,*]=0,则finish[k]:=true;否则finish[k]:=false;这里k=1,..,n

(3)在剩余的进程集合中找一个进程Pk,需满足条件:

finish[k]=false&(request[*]≤Work)

找到这样的Pk便转(4);否则转(5)

(4)Work:= Work + Allocation;finish[k]:=true;然后转(3)

(5) 如果对k=1,..,n若finish[k]=true不成立,那么,系统出现了死锁,并且finish[k]=false的Pk为死锁进程。

源程序:

#include <string.h>
#include <iostream.h>
#define FALSE 0
#define TRUE 1
#define W 10   //最大进程数W=10
#define R 20   //最大资源总数R=20
int M;
int N;
int ALL_RESOURCE[W];
int AVAILABLE[R];     //可利用资源向量
int MAX[W][R];   //最大需求矩阵
int ALLOCATION[W][R]; //分配矩阵
int NEED[W][R];       //需求矩阵
int Request[R];    //进程请求向量
void inputdata();    //数据输入
void showdata();       //数据显示
void changdata(int k);//进程请求资源数据改变
void restoredata(int k); //数据恢复
int  chksec(int s); //系统安全性的检测
int  chkmax(int s); //检测最大需求
void bank();   //检测分配的资源是否合理   

void main()
{
    int i,j;
    inputdata();
    for(i=0;i<M;i++)
    { j=chksec(i);
    if (j==0)
        break;
    }
    if (i>=M)
        cout<<"错误提示:经安全性检查发现,系统的初始状态不安全!!!\n"<<endl;
    else
    {
        cout<<"提示:经安全性检查发现,系统的初始状态安全!"<<endl;
        bank();
    }
}  

void inputdata()
{
    int i=0,j=0,p;
    cout<<"请输入总进程数:"<<endl;
    do
    {
        cin>>M;
        if (M>W)
            cout<<endl<<"总进程数超过了程序允许的最大进程数,请重新输入:"<<endl;
    }while (M>W);
    cout<<endl;
    cout<<"请输入资源的种类数:"<<endl;
    do
    {
        cin>>N;
        if (N>R)
            cout<<endl<<"资源的种类数超过了程序允许的最大资源种类数,请重新输入:"<<endl;
    }while (N>R);
    cout<<endl;
    cout<<"请依次输入各类资源的总数量,即设置向量all_resource:"<<endl;
    for(i=0;i<N;i++)
        cin>>ALL_RESOURCE[i];
    cout<<endl;
    cout<<"请依次输入各进程所需要的最大资源数量,即设置矩阵max:"<<endl;
    for (i=0;i<M;i++)
    {
        for (j=0;j<N;j++)
        {
            do
            {
                cin>>MAX[i][j];
                if (MAX[i][j]>ALL_RESOURCE[j])
                    cout<<endl<<"该最大资源数量超过了声明的该资源总数,请重新输入:"<<endl;
            }while (MAX[i][j]>ALL_RESOURCE[j]);
        }
    }
    cout<<endl;
    cout<<"请依次输入各进程已经占据的各类资源数量,即设置矩阵allocation:"<<endl;
    for (i=0;i<M;i++)
    {
        for (j=0;j<N;j++)
        {
            do
            {
                cin>>ALLOCATION[i][j];
                if (ALLOCATION[i][j]>MAX[i][j])
                    cout<<endl<<"已占有的资源数量超过了声明的最大资源数量,请重新输入:"<<endl;
            }while (ALLOCATION[i][j]>MAX[i][j]);
        }
    }
    cout<<endl;
    for (i=0;i<M;i++)
        for(j=0;j<N;j++)
            NEED[i][j]=MAX[i][j]-ALLOCATION[i][j];
        for (j=0;j<N;j++)

   {
            p=ALL_RESOURCE[j];
            for (i=0;i<M;i++)
            {
                p=p-ALLOCATION[i][j];
                AVAILABLE[j]=p;
                if(AVAILABLE[j]<0)
                    AVAILABLE[j]=0;
            }    

        }
}   

void showdata()
{
    int i,j;
    cout<<"各种资源的总数量,即向量all_resource为:"<<endl;
    cout<<" ";
    for (j=0;j<N;j++)
        cout<<" 资源"<<j<<": "<<ALL_RESOURCE[j];
    cout<<endl<<endl;
    cout<<"当前系统中各类资源的可用数量,即向量available为:"<<endl;
    cout<<" ";
    for (j=0;j<N;j++)
        cout<<" 资源"<<j<<": "<<AVAILABLE[j];
    cout<<endl<<endl;
    cout<<"各进程还需要的资源数量,即矩阵need为:"<<endl<<endl;
    for (i=0;i<M;i++)
    {
        cout<<"进程P"<<i<<":   ";
        for (j=0;j<N;j++)
            cout<<NEED[i][j]<<"        ";
        cout<<endl;
}
    cout<<endl;
    cout<<"各进程已经得到的资源量,即矩阵allocation为: "<<endl<<endl;
    for (i=0;i<M;i++)
    {
        cout<<"进程P"<<i<<":    ";
        for (j=0;j<N;j++)
            cout<<ALLOCATION[i][j]<<"       ";
        cout<<endl;
    }
    cout<<endl;
}     

void changdata(int k)
{
    int j;
    for (j=0;j<N;j++)
    {
        AVAILABLE[j]=AVAILABLE[j]-Request[j];
        ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];
        NEED[k][j]=NEED[k][j]-Request[j];
    }
}    

void restoredata(int k)
{
    int j;
    for (j=0;j<N;j++)
    {
        AVAILABLE[j]=AVAILABLE[j]+Request[j];
        ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];
        NEED[k][j]=NEED[k][j]+Request[j];
    } 

}   

int chksec(int s)
{
    int WORK,FINISH[W];
    int i,j,k=0;
    for(i=0;i<M;i++)
        FINISH[i]=FALSE;
    for(j=0;j<N;j++)
    {
        WORK=AVAILABLE[j];
        i=s;
        do
        {
            if(FINISH[i]==FALSE&&NEED[i][j]<=WORK)
            {
                WORK=WORK+ALLOCATION[i][j];
                FINISH[i]=TRUE;
                i=0;
            }
            else
            {
                i++;
            }
        }while(i<M);
        for(i=0;i<M;i++)
            if(FINISH[i]==FALSE)
            {
                return 1;
            }
    }
    return 0;
}    

int chkmax(int s)
{
    int j,flag=0;
    for(j=0;j<N;j++)
    {
        if (MAX[s][j]==ALLOCATION[s][j])
        {
            flag=1;
            AVAILABLE[j]=AVAILABLE[j]+MAX[s][j];
            MAX[s][j]=0;
        }
    }
    return flag;
}

void bank()
{
    int i=0,j=0;
    char flag=‘Y‘;
    while(flag==‘Y‘||flag==‘y‘)
    {
        i=-1;
        while(i<0||i>=M)
        {
            cout<<"请输入需申请资源的进程号(从P0到P"<<M-1<<",否则重新输入!):";
            cout<<"p";    cin>>i;
            if(i<0||i>=M)
                cout<<"输入的进程号不存在,重新输入!"<<endl;
        }
        cout<<"请输入进程P"<<i<<"申请的资源数:"<<endl;
        for (j=0;j<N;j++)
        {
            cout<<"  资源"<<j<<": ";
            cin>>Request[j];
            if(Request[j]>NEED[i][j])
            {
                cout<<"进程P"<<i<<"申请的资源数大于进程P"<<i<<"还需要"<<j<<"类资源的资源量!";
                cout<<"申请不合理,出错!请重新选择!"<<endl<<endl;
                flag=‘N‘;
                break;
}
            else
            {
                if(Request[j]>AVAILABLE[j])
                {
                    cout<<"进程P"<<i<<"申请的资源数大于系统可用"<<j<<"类资源的资源量!";
                    cout<<"申请不合理,出错!请重新选择!"<<endl<<endl;
                    flag=‘N‘;
                    break;
                }       

            }
}
        if(flag==‘Y‘||flag==‘y‘)
        {
            changdata(i);
            if(chksec(i))
            {
                cout<<endl;
                cout<<"该分配会导致系统不安全!!! 本次资源申请不成功,不予分配!!!"<<endl;
                cout<<endl;
                restoredata(i);
}
            else
            {
                cout<<endl;
                cout<<"经安全性检查,系统安全,本次分配成功,且资源分配状况如下所示:"<<endl;
                cout<<endl;
                showdata();
                if(chkmax(i))
                {
                    cout<<"在资源分配成功之后,由于该进程所需的某些资源的最大需求量已经满足,"<<endl;
                    cout<<"因此在进程结束后系统将回收这些资源!"<<endl;
                    cout<<"在资源收回之后,各进程的资源需求和分配情况如下所示:"<<endl;
                    showdata();
                }          

            }
}
        cout<<endl;
        cout<<" 是否继续银行家算法演示,按‘Y‘或‘y‘键继续,按‘N‘或‘n‘键退出演示: ";
        cin>>flag;
    }
}

运行结果:

时间: 2024-10-10 14:33:22

操作系统之银行家算法避免死锁的相关文章

操作系统之银行家算法

一.需求分析 1.进程的状态有:就绪,等待和完成.当系统不能满足进程的资源请求时,进程出于等待状态.资源需求总量表示进程运行过程中对资源的总的需求量.已占资源量表示进程目前已经得到但还为归还的资源量.因此,进程在以后还需要的剩余资源量等于资源需要总量减去已占资源量.陷入每个进程的资源需求总量不应超过系统拥有的资源总量. 2.银行家算法分配资源的原则是:当某个进程提出资源请求时,假定先分配资源给它,然后查找各进程的剩余请求,检查系统的剩余资源量是否由于进程的分配而导致系统死锁.若能,则让进程等待,

【操作系统】银行家算法

[操作系统]银行家算法 2017-05-10 若愚 上次介绍了死锁的相关概念,以及各种解决办法.今天讲的是死锁避免里面的银行家算法.请多多指教~ 一.算法的背景 算法由迪杰斯特拉在1965年提出. 在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还.银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要.在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程. 二.算

银行家算法避免死锁

系统安全状态的定义 1.安全状态 在避免死锁的方法中,允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性.若此次分配不会导致系统进入不安全状态,则将资源分配给进程:否则,令进程等待. 虽然并非所有的不安全状态都必然会转为死锁状态,但当系统进入不安全状态后,便有可能进而进入死锁状态:反之,只要系统处于安全状态,系统便可避免进入死锁状态. 因此,避免死锁的实质在于:系统在进行资源分配时,如何使系统不进入不安全状态. 利用银行家算法避免死锁 1.银行家算法中的数据结构 (1

操作系统:银行家算法(避免死锁)

算法介绍: 程序实现: /***************************************************** 程序:银行家算法实现 作者:小单 时间: 2013年11月5日 ******************************************************/ #include <iostream> #include <string> using namespace std; #define MAXPROCESS 50 //所能执行的

利用银行家算法避免死锁的介绍与举例

一.数据结构 1.多个进程: { P0,P1,P2,P4 } 代表1,2,3,4四个需要临界资源的进程 2.几种资源:{ A, B ,C } 代表A,B,C三种临界资源 3.Max:最大需求矩阵(进程完成执行需要的各资源总量)   Allocation:分配矩阵(某个进程现在已经拥有的各资源量)   Need:需求矩阵(某个进程仍需要的各资源量)   Available:可利用资源向量 (系统保有的供分配的资源量)   其中:Need = Max - Allocation ,很容易理解嘛,仍然需

c/c++多线程模拟系统资源分配(并通过银行家算法避免死锁产生)

#include<iostream> #include<cstdio> #include<vector> #include<ctime> #include<cstring> #include<unistd.h> #include<cstdlib> #define RESTYPE 100 //资源的种类数 #define NTHREAD 50 //线程的数目 using namespace std; pthread_mute

【操作系统】处理机调度与死锁(三)

一.前言 前面介绍了进程与线程的相关概念,现在继续学习处理机调度,处理机是系统最重要的资源,提高处理机的利用率和改善系统性能,在很大程度上取决于处理机调度性能的好坏,下面来介绍处理的调度以及死锁的问题. 二.处理机调度的层次 2.1 高级调度 高级调度又称为作业调度或长程调度,主要功能是根据某种算法,把外存上处于后备队列中的那些作业调入内存,调度的对象是作业. 作业,包含了程序.数据.作业说明书,系统根据该作业说明书来控制程序的运行.在批处理系统中,是以作业为基本单位从外存调入内存的. 作业步,

银行家算法实例(转)

在网上找了一篇不可多的的讲银行家算法的例题的博文,mark下来.作者写的还是不错,简单易懂,比单纯讲含义要实用的多. 转自: 木轩琰的博客 最近开始备考计算机四级,基本没有遇到什么问题,感觉计算机四级就是考理解型记忆力,银行家算法的题算是在计算机四级里少有的计算题. 例1.设系统中有三种类型的资源(A,B,C)和五个进程(P1,P2,P3,P4,P5),A资源的数量是17,B资源的数量是6,C资源的数量为19.在T0时刻系统的状态如下表:   最大资源需求量 已分配资源量   A,B,C A,B

银行家算法学习笔记

     上周操作系统的实验,就是模拟实现银行家算法,首先我们还是应该对银行家算法熟悉一下. 银行家算法是最具代表性的避免死锁的算法.因为该算法原本是为银行系统设计的,以确保银行在发放现金贷款时,不会发生不满足所有客户需求的情况.在OS中也可它来实现避免死锁. 算法概述: 为实现银行家算法,每一个进程在进入系统时,它必须申明在运行过程中,可能需要每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量,当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程.若有,再进一步计算在