OS 银行家算法

来源:互联网 发布:淘宝个体工商户 编辑:程序博客网 时间:2024/06/15 22:53

银行家算法

更新:

1.安全算法检查,应当是 work>need2.安全算法代码    2.1输入时,计算need-=allocation    2.2判断使,work>need

一、实验目的理解银行家算法,掌握进程安全性检查的方法及资源分配的方法。二、实验内容编写程序实现银行家算法,并验证程序的正确性。三、实验要求编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性。例子:某系统有A、B、C、D 4类资源共5个进程(P0、P1、P2、P3、P4)共享,各进程对资源的需求和分配情况如下表所示。现在系统中A、B、C、D 4类资源分别还剩1、5、2、0个,请按银行家算法回答下列问题:(1)现在系统是否处于安全状态?安全(2)如果现在进程P1提出需求(0、4、2、0)个资源的请求,系统能否满足它的请求?满足

os3

  • 分析:
    • 银行家算法是为避免死锁设计的,主要内容为:
      1.试探分配
      2.进行安全检查
       该算法寄托于上述两步来实现避免进程推进过程中的不安全状态。
    • 安全检查分析:
      1.很简单,就是每次查找 当前资源>该进程仍需的资源(work>need)的进程,找到该进程后可释放进程,使资源宽松—–>(其实就是:当前资源+该进程已经分配的资源 > 最大所需资源,work+allocation>max) 。
      2.继续查找,直到最后所有的进程状态都为finish=true,则安全;若仍有finish=false,且找不到资源可满足的
      进程则为不安全,当前的分配可导致死锁。
  • 数据结构
  系统:    Available [a,b,c,d,...]  进程(PCB):    MAX [a,b,c,d,...] 是个常量,为最初创建进程时,所声明的最大需求矩阵    need[a,b,c,d,...] 表示当前还需资源矩阵,初始值为MAX    allocation[a,b,c,d,...] 表示已经分配资源矩阵  安全性检查算法DS        work[a,b,c,d,...] 为Available的一个副本,用来进程安全检查中的计算,每次检查的初值为系统当前Available值    finish[...] 表示进程分配结束标志
  • 模拟

    进程资源存储在PCB_RES中,每次分配按银行加算法分配。1.当 request>need 出错;否则22.当 request>availabe 资源不足,wait;否则33.安全算法检查    3.1.查找 当前资源>该进程仍需要资源 的进程(即work>need),找到该进程后可释放资源    3.2.继续查找,直到最后所有的进程状态都为finish=true,则安全;        若仍有finish=false,且找不到资源可满足的,进程则为不安全,当前的分配可导致死锁。
  • code(ubuntu16.04 g++):
#include<iostream>#include<vector>#include<cstdio>using namespace std;/* * sys: * Avalible * * process: * need (= max initial) * allocation * * need+allocation=max *  * security: * work (=avlible initial) * */const int MAX=4;int Available[MAX]={1,5,2,0};bool finish[5]={false};int work[MAX];struct PCB_RES{    int num;    int need[MAX];    int allocation[MAX];    int request[MAX];};vector<PCB_RES>res_wait;vector<PCB_RES>run;PCB_RES *getPCB(int p){    for(int i=0;i<run.size();i++)    {        if(p==run.at(i).num)          return &run.at(i);    }    cout<<"getPCB error"<<endl;    return NULL;}bool request(int proc,int *res,int size){    cout<<"processs:"<<proc<<" is requesting!"<<endl;    //小于need    int flag=0;    PCB_RES* p=getPCB(proc);    if(p==NULL)      return false;    for(int i=0;i<size;i++)    {        p->request[i]=res[i];        cout<<res[i]<<"-"<<p->need[i]<<endl;        if(res[i]>p->need[i])        {          flag=1;          cout<<"error:request > need!"<<endl;          break;        }    }    if(flag!=0)      return false;    for(int i=0;i<size;i++)    {        if(res[i]>Available[i])        {          flag=2;          cout<<"error:request > Available"<<flag<<endl;          break;        }    }    if(flag==2)    {        //wait,加入wait队列,每次轮转检查        res_wait.push_back(*p);        //移除run        for(int i=0;i<run.size();i++)        {            if(run[i].num==proc)            {                run.erase(run.begin()+i);                break;            }        }        cout<<"资源不足,进程等待!"<<endl;        return false;    }else        return true;}//安全检查仅进行安全检查--就是找能够得到资源的进程,使用完后,释放,增加//系统资源数---直到最后还有未结束的进程且资源不够时系统是不安全的。//若所有进程都分配完全则是安全的。//-1 安全,-2不安全,n>=0,返回 pcb在run中的序号int getAvaibleP(vector<PCB_RES>*ptmp,int *fin,int count,int *work,int size){    int haveOne=0;    int fin_c=0;    int i=0;    //processes    for(i=0;i<count;i++)    {        if(fin[i]==false)        {            int flag=0;            int j=0;            cout<<"p"<<i<<endl;            //res            cout<<"w\tn"<<endl;            for(j=0;j<size;j++)            {                cout<<work[j]<<"\t"<<(ptmp->at(i)).need[j]<<endl;                if((work[j]<(ptmp->at(i)).need[j]))                {                    cout<<"get no"<<endl;                    flag=1;                    break;                }            }            if(flag==1)              continue;            else            {                haveOne=1;                break;            }        }else          fin_c++;    }    if(fin_c==count)      return -1;    if(haveOne==1)      return i;    else      return -2;}//安全性检查,使用前要设置好workbool check(){    cout<<"安全性检查"<<endl;    //aquire the copys    vector<PCB_RES>run_tmp=run;    int finish[100]={0};    //the max number of checking most is run.size()    for(int i=0;i<run.size();i++)    {        int status= getAvaibleP(&run_tmp,finish,run.size(),work,MAX);        cout<<"status"<<status<<endl;        //安全        if(status==-1)        {            //确认分配            cout<<"确认分配"<<endl;            return true;        }else if(status==-2)        {            cout<<"分配失败"<<endl;            return false;        }else if(status>=0)        {            cout<<"发现进程"<<status<<"资源可分配结束,释放资源"<<endl;            //模拟分配,释放资源            for(int i=0;i<MAX;i++)            {                cout<<run_tmp[status].allocation[i]<<" ";                work[i]+=run_tmp[status].allocation[i];            }            cout<<endl;            finish[status]=1;        }    }    return true;}bool allocate(int proc,int *res,int size){    //check 1:    //request>need return false    //request>avalible return false and set process into wait queue    if(request(proc,res,size)==false)      return false;    //safety check    PCB_RES*p=getPCB(proc);    if(p==NULL)      return false;    //初始化    for(int i=0;i<MAX;i++)      work[i]=Available[i];    //try allocating    cout<<"try allocatin"<<endl;    for(int i=0;i<size;i++)    {        work[i]-=res[i];        p->need[i]-=res[i];        p->allocation[i]+=res[i];    }    if(check()==false)    {        cout<<"check失败,返还资源"<<endl;        //分配失败,返还资源        for(int i=0;i<size;i++)        {            p->need[i]+=res[i];            p->allocation[i]-=res[i];        }    }else    {        for(int i=0;i<size;i++)            Available[i]-=res[i];        //资源分配够,进释放,停止该进程        int flag=0;        for(int i=0;i<size;i++)        {            if(p->allocation[i]!=p->need[i])            {              flag=1;              break;            }        }        if(flag==0)        {            cout<<"释放资源"<<endl;            for(int i=0;i<size;i++)            {                Available[i]+=p->allocation[i];            }        }        return true;    }}//检查等待队列PCB_RES*  getWaitOut(){    cout<<"checking in wait queue"<<endl;    int flag=0;    for(int i=0;i<res_wait.size();i++)    {        flag=0;        for(int j=0;j<MAX;j++)        {            if(res_wait[i].request[j]>Available[j])            {                flag=1;                break;            }        }        if(flag==0)        {            //移出res_wait到run中,由外部重新分配            run.push_back(res_wait[i]);            res_wait.erase(res_wait.begin()+i);            return &run.at(run.size()-1);        }    }    return NULL;}void showA(){    cout<<"current Available:"<<endl;    for(int i=0;i<MAX;i++)    {      cout<<Available[i]<<" ";    }    cout<<endl;}int main(){    freopen("in","r",stdin);    int count=0;    cout<<"选择创建进程数"<<endl;    cin>>count;    cout<<"初始化进程分配资源和最大需要数,共ABCD四种资源"<<endl;    int a[MAX];    int b[MAX];    int p;    PCB_RES res_tmp;    for(int i=0;i<count;i++)    {        res_tmp.num=i;        for(int j=0;j<MAX;j++)            cin>>res_tmp.allocation[j];        for(int j=0;j<MAX;j++)        {            cin>>res_tmp.need[j];            //need=max            //need=need-allocation            res_tmp.need[j]-=res_tmp.allocation[j];        }        run.push_back(res_tmp);    }    for(int i=0;i<MAX;i++)      work[i]=Available[i];    if(check()==true)      cout<<"初始安全"<<endl;    else      cout<<"初始不安全"<<endl;    int tmp=0;    while(true)    {        cout<<"------------------------------------------"<<endl;        PCB_RES *pcb=getWaitOut();        if(pcb!=NULL)        {            cout<<"唤醒进程:"<<pcb->num<<"重新分配资源"<<endl;            if(allocate(pcb->num,pcb->request,MAX)==true)              cout<<"已分配"<<endl;            else              cout<<"分配失败"<<endl;        }        //check res wait queue        cout<<"分配资源(进程号,资源数)1,退出2"<<endl;        cin>>tmp;        if(tmp==1)        {            showA();            cin>>p;            cout<<"process:"<<p<<" requests:"<<endl;            for(int j=0;j<MAX;j++)            {                cin>>a[j];                cout<<a[j]<<" ";            }            cout<<endl;            if(allocate(p,a,MAX)==true)              cout<<"已分配"<<endl;            else              cout<<"分配失败"<<endl;        }else          break;    }    return 0;}
  • 测试数据
    数据1    5    0 0 1 2 0 0 1 2    1 0 0 0 1 7 5 0    1 3 5 4 2 3 5 6    0 6 3 2 0 6 5 2    0 0 1 4 0 6 5 6    1    1 0 5 3 0    1    0 0 0 0 0    1    4 1 1 0 0    2    数据2    5    0 0 1 2 0 0 1 2    1 0 0 0 1 7 5 0    1 3 5 4 2 3 5 6    0 6 3 2 0 6 5 2    0 0 1 4 0 6 5 6    1    1 0 4 2 0    2
原创粉丝点击