操作系统之银行家算法

一、需求分析

1、进程的状态有:就绪,等待和完成。当系统不能满足进程的资源请求时,进程出于等待状态。资源需求总量表示进程运行过程中对资源的总的需求量。已占资源量表示进程目前已经得到但还为归还的资源量。因此,进程在以后还需要的剩余资源量等于资源需要总量减去已占资源量。陷入每个进程的资源需求总量不应超过系统拥有的资源总量。

2、银行家算法分配资源的原则是:当某个进程提出资源请求时,假定先分配资源给它,然后查找各进程的剩余请求,检查系统的剩余资源量是否由于进程的分配而导致系统死锁。若能,则让进程等待,否则,让进程的假分配变为真分配。

(1)查找各进程的剩余请求,检查系统的剩余资源量是否能满足其中一进程,如果能,则转B)。

(2)将资源分配给所选的进程,这样,该进程已获得资源最大请求,最终能运行完成。标记这个进程为终止进程,并将其占有的全部资源归还给系统。

重复第(1)(2)步,直到所有进程都标记为终止进程,或知道一个死锁发生。若所有进程都标记为终止进程,则系统的初始状态是安全的,否则为不安全的。若安全,则正式将资源分配给它,否则,假定的分配作废,让其等待。

二、系统结构设计

1、设计分析

当某个进程对某类资源提出请求时,假定先分配资源给它,然后查找各进程的剩余请求,检查系统的剩余资源量是否由于进程的分配而导致系统死锁。若能,则让进程等待,否则,让进程的假分配变为真分配。

2、数据结构

1)可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可利用资源的数目,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可利用资源的数目,其数值随该类资源的分配和回首而动态的改变,如果Available=K,则代表Rj类资源K个。

2)最大需求矩阵Max。这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。

3)分配矩阵Allocation。这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。

4)需求矩阵Need。这也是一个n×m的矩阵,用以表示每一个进程还需要各类资源数。

3、银行家算法

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

A:如果Requesti[j]<=Need[i,j],执行B,否则认为出错,因为它需要的资源数已经超过它所宣布的最大值。

B: 如果Requesti[j]<=Available[j],转向步骤C,否则尚无足够资源,Pi必须等待。

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

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

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

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

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

设置WORK[R]是系统可提供给进程继续运行所需的各类资源数目刚开始 系统可提供给进程继续运行所需的j类资源数目,FINISH[i]检查安全性是否通过。

4程序流程图

三、总结和体会

 通过在刘玉宏老师的帮助下,我成功的完成了这次课程设计,虽然其中存在很多的不足。在这个银行家算法课程设计中,利用二维数组作为基本的数据结构用以存储资源及进程信息,利用check()函数来判断进程执行是否安全,通过二维数组和distribute ()restore()函数很好的解决了进程的分配及撤销问题。 

实验中我使用当一个进程不满足安全状态时紧接着查找它的下一个进程,若下一个进程满足则给予分配资源,然后又返回从头开始才找满足安全状态的进程,经过刘老师的课堂讲解我知道还可以按照进程的编号从小到大一次下循环查找,直到进程执行完毕。 

不同的算法可以实现相同的功能,这是我从本次实验中深深体会到的,因而在今后的学习中遇到问题我会尝试着用的不同的方法来解决,有时候换个角度可以很方便的解决问题。

四、主要算法清单

#include <string.h>

#include <iostream.h>

#define FALSE 0 

#define TRUE 1 

#define W 10  

#define R 10

int M ; //总进程数

int N ; //资源种类 

int All[W];//各种资源的数目总和

int Max[W][R]; //M个进程对N类资源最大资源需求量

int Available[R]; //系统可用资源数

int Allocation[W][R]; //M个进程已经得到N类资源的资源量

int Need[W][R]; //M个进程还需要N类资源的资源量

int Request[R]; //请求资源个数

 

void output() //输出资源分配情况

   int i,j;

   cout<<endl<<"*************************"<<endl; 

   cout<<"各种资源的总数量:"<<endl; 

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

   cout<<" 资源"<<j<<": "<<All[j]<<endl; 

   cout<<endl; 

   cout<<"*************************"<<endl; 

   cout<<"目前各种资源可利用的数量为:"<<endl; 

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

   cout<<"    资源"<<j<<": "<<Available[j]<<endl; 

   cout<<endl<<endl; 

   cout<<"*************************"<<endl; 

   cout<<"各进程还需要的资源数量:"<<endl; 

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

   { cout<<"     资源"<<j<<"  "; }

   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; 

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

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

   { cout<<"       资源"<<j<<"  "; }

   cout<<endl;

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

   { 

     cout<<"进程"<<i<<":    "; 

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

  cout<<Allocation[i][j]<<"           "; 

     cout<<endl; 

   } 

   cout<<endl; 

void distribute(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];//k个进程对第j中资源还需要的资源量

   }

}

void restore(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 check() //检查安全性

 int WORK[R],FINISH[W];//WORK[R]是系统可提供给进程继续运行所需的各类资源数目 

    int i,j; 

 for(j=0;j<N;j++) WORK[j]=Available[j];//刚开始 系统可提供给进程继续运行所需的j类资源数目 等于j类可用资源数目

    for(i=0;i<M;i++) FINISH[i]=FALSE; 

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

{

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

     {

         if(FINISH[i]==FALSE&&Need[i][j]<=WORK[j])

         {

            WORK[j]=WORK[i]+Allocation[i][j]; 

         } 

     }

  FINISH[i]=TRUE; 

}

 

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

    {

        if(FINISH[i]==FALSE) 

        {

           cout<<endl; 

           cout<<" 系统不安全本次资源申请不成功!!!"<<endl; 

           cout<<endl; 

           return 1; 

        } 

        else

{

           cout<<endl; 

           cout<<" 经安全性检查,系统安全,本次分配成功。"<<endl; 

           cout<<endl; 

           

}

    }

 return 0; 

}

void bank()   //银行家算法

{

    int i=0,j=0; 

    char flag='Y'; 

    while(flag=='Y'||flag=='y') 

    { 

      i=-1; 

      while(i<0||i>=M) 

      { 

        cout<<"***********************************"<<endl;

         cout<<endl<<" 请输入需申请资源的进程号:"; 

 cin>>i; 

         if(i<0||i>=M)  cout<<" 输入的进程号不存在,重新输入!"<<endl; 

      }

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

      { 

       cout<<" 资源"<<j<<": "; 

       cin>>Request[j];

        if(Request[j]>Need[i][j]) //若请求的资源数大于进程还需要i类资源的资源量j

         cout<<endl<<" 进程"<<i<<"申请的资源数大于进程"<<i<<"还需要"<<j<<"类资源的数量!"; 

 cout<<" 若继续执行系统将处于不安全状态!"<<endl;

 flag='N'; 

         break; 

  

        else 

{

          if(Request[j]>Available[j]) //若请求的资源数大于可用资源数

 { 

            cout<<endl<<" 进程"<<i<<"申请的资源数大于系统可用"<<j<<"类资源的数量!"; 

            cout<<" 若继续执行系统将处于不安全状态!"<<endl;

            flag='N'; 

            break; 

          } 

      } 

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

      { 

        distribute(i); //调用change(i)函数,改变资源数

        if(check()) //若系统安全

          restore(i); //调用restore(i)函数,恢复资源数

          output();   //输出资源分配情况

        else       //若系统不安全 

          output(); //输出资源分配情况 

      } 

      else      //flag=N||flag=n 

        cout<<endl; 

        cout<<" 是否继续银行家算法演示,'Y''y'键继续,'N''n'键退出演示: "; 

        cin>>flag; 

   } 

void version() 

  cout<<endl; 

  cout<<"\t*************************"<<endl; 

  cout<<"\t*                       *"<<endl;

  cout<<"\t*  银 行 家 算 法    *"<<endl; 

  cout<<"\t*                       *"<<endl;

  cout<<"\t*************************"<<endl; 

void main() //主函数

   int i=0,j=0,p; 

   version();

   cout<<endl<<"请输入总进程数:";

   cin>>M;

   cout<<endl<<"***************************"<<endl; 

   cout<<"请输入总资源种类:";

   cin>>N;

   cout<<endl<<"***************************"<<endl; 

   cout<<"请输入各类资源总数:";

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

   cin>>All[i];

   cout<<endl<<"***************************"<<endl; 

   cout<<"输入各进程所需要的各类资源的最大数量:"<<endl;

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

   {

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

     {

       do

       {

         cin>>Max[i][j];

         if (Max[i][j]>All[j])

         cout<<endl<<"占有资源超过了声明的该资源总数,请重新输入"<<endl;

       }while (Max[i][j]>All[j]);

     }

   }

  cout<<endl<<"********************************"<<endl; 

  cout<<"输入各进程已经分配的各类资源的数量:"<<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]);

    }

  }

  for (j=0;j<N;j++)  //初始化资源数量

  {

 p=All[j];

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

    {

      p=p-Allocation[i][j];//减去已经被占据的资源

      Available[j]=p;

      if(Available[j]<0)

      Available[j]=0;

    }

  }

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

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

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

  output();

  bank();

}

5 银行家算法实现 5.1 实验类型 设计型(4学时)。 5.2 实验目的 1) 理解死锁避免相关内容; 2) 掌握银行家算法主要流程; 3) 掌握安全性检查流程。 5.3 实验描述 本实验主要对操作系统中的死锁预防部分的理论进行实验。要求实验者设计一个程序,该程序可对每一次资源申请采用银行家算法进行分配。 5.4 实验内容 1) 设计多个资源(≥3); 2) 设计多个进程(≥3); 3) 设计银行家算法相关的数据结构; 4) 动态进行资源申请、分配、安全性检测并给出分配结果。 5.5 实验要求 1) 编写程序完成实验内容; 2) 画出安全性检测函数流程图; 3) 撰写实验报告。 5.6 测试要求 1) 进行Request请求,输入参数为进程号、资源号和资源数; 2) 进行3次以上的Request请求; 3) 至少进行1次资源数目少于可用资源数,但不安全的请求。 5.7 相关知识 5.7.1 银行家算法的数据结构 1) 可利用资源向量Available。其中每个元素代表每类资源的数目。 2) 最大需求矩阵Max。其中每个元素代表每个进程对于每类资源的最大需求量。Max[i,j]=K表示i进程对于j类资源的最大需求量为K。 3) 分配矩阵Allocation。其中每个元素代表每个进程已得到的每类资源的数目。 4) 需求矩阵Need。其中每个元素代表每个进程还需要的每类资源的数目。 5.7.2 银行家算法 Request i [j]=K表示进程Pi需要K个j类资源。 1) 如果Request i [j]≤Need[i , j],便转向步骤2,否则认为出错。 2) 如果Request i [j]≤Available[j],便转向步骤3,否则表示无足够资源,Pi需等待; 3) 系统尝试分配资源给Pi; 4) 系统进行安全性检查,检查此次资源分配后,系统是否安全。如果安全,则正式分配资源,否则撤销此次分配。 5.7.3 安全性算法 1) 设置两个向量:工作向量Work和Finish。算法开始时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[j]+Allocation[i , j]; Finish[i] = True; 到第2)步。 4) 直到所有Finish[i]=True,表示系统处于安全状态;否则系统处于不安全状态。 5.8 实验设备 PC机1台,要求安装DOS7.1、Turbo C3.0、Windows2000。 5.9 实验成绩评定 实验成绩评定方式包含实验报告成绩、实验过程成绩两个部分,其中实验过程成绩占60%、实验报告成绩占40%,如果其中任何一个部分成绩不及格,则总成绩按不及格处理。 5.10 实验报告 按照实验目的、实验内容、实验要求、实验设备、测试等部分进行组织。 5.11 实验思考 1) 针对死锁有哪些可行方案? 2) 死锁解除的难点是什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值