zoukankan      html  css  js  c++  java
  • 操作系统之银行家算法

    一、实验目的

      通过编写一个模拟动态资源分配的银行家算法程序,进一步深入理解死锁、产生死锁的必要条件、安全状态等重要概念,并掌握避免死锁的具体实施方法。

    二、实验内容

    (1)模拟一个银行家算法: 设置数据结构 设计安全性算法(2) 初始化时让系统拥有一定的资源
    (3) 用键盘输入的方式申请资源
    (4)如果预分配后,系统处于安全状态,则修改系统的资源分配情况
    (5)如果预分配后,系统处于不安全状态,则提示不能满足请求

    三、实验要点说明

    数据结构

    可利用资源向量 int Available[m] m为资源种类
    最大需求矩阵 int Max[n][m] n为进程的数量
    分配矩阵 int Allocation[n][m]
    还需资源矩阵 int need[i][j]=Max[i][j]- Allocation[i][j]
    申请资源数量 int Request [m]
    工作向量 int Work[m] int Finish[n]
    银行家算法bank()函数

    Requesti:进程Pi的请求向量。 0<=j<=m-1

    (1) 若 Requesti[j] ≤ Need[i,j],转向(2),否则出错。
    (2) 若 Requesti[j] ≤ Available[j],转向(3),否则等待。
    (3) 系统试探着把资源分配给进程Pi,修改下面内容:
    Available[j] = Available[j] – Requesti[j];
    Allocation[i,j] = Allocation[i,j] + Requesti[j];
    Need[i,j] = Need[i,j] –Requesti[j];
    (4) 试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试探性分配作废,进程Pi等待。

    安全性算法safe()函数

    (1) 初始化:设置两个向量Work(1×m)和Finish(1×n)
    Work – 系统可提供给进程继续运行所需各类资源数,初态赋值Available
    Finish – 系统是否有足够资源分配给进程,初值false.
    (2) 从进程集合中满足下面条件进程:
    Finish[i] = false; Need[i,j] ≤ Work[j];
    若找到,执行(3),否则,执行(4)。
    (3) 进程Pi获得资源,可顺利执行,完成释放所分配的资源。
    Work[j] = Work[j]+Allocation[i,j]; Finish[i] = true; go to (2).
    (4) 若所有进程Finish[i] = true,表示系统处于安全状态,否则处于不安全状态。
    先对用户提出的请求进行合法性检查,即检查请求的是否不大于需要的,是否不大于可利用的。 若请求合法,则进行试分配。最后对试分配后的状态调用安全性检查算法进行安全性检查。 若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。

    银行家算法实例

    假定系统中有五个进程{P0、P1、P2、P3、P4}和三种类型资源{A、B、C},每一种资源的数量分别为10、5、7。各进程的最大需求、T0时刻资源分配情况如下所示。

    试问:

    ①T0时刻是否安全?
    ② T0之后的T1时刻P1请求资源Request1(1,0,2)是否允许?
    ③ T1之后的T2时刻P4请求资源Request4(3,3,0)是否允许?
    ④ T2之后的T3时刻P0请求资源Request0(0,2,0)是否允许?
    解:

    ① T0时刻是否安全? 工作向量Work.它表示系统可提供给进程继续运行所需要的各类资源的数目

    (1) T0时刻安全性分析

    存在安全序列{P1, P3, P4, P0, P2},系统安全。

    (2) T0之后的T1时刻P1请求资源Request1(1,0,2)可否允许?

    ①Request1(1,0,2) ≤ Need1(1,2,2),P1请求在最大需求范围内
    ②Request1(1,0,2) ≤ Available1(3,3,2),可用资源可满足P1请求需要
    ③假定可为P1分配,修改Available,Allocation1,Need1向量
    Available(2,3,0) = Available(3,3,2)-Request1(1,0,2);
    Need1(0,2,0) = Need1(1,2,2)-Request1(1,0,2);
    Allocation1(3,0,2) =Allocation1(2,0,0)+Request1(1,0,2);
    ④利用安全性算法检查试探将资源分配后状态的安全性

    存在安全序列{P1, P3, P4, P0, P2},所以试探将资源分配给进程P1后的状态是安全的,可将资源分配给进程P1。

    ③ T1之后的T2时刻P4请求资源Request4(3,3,0)是否允许?

    Request4(3,3,0)≤Need4(4,3,1),P4请求在最大需求范围内。
    Request4(3,3,0)≤Available(2,3,0)不成立,即可用资源暂不能满足P4请求资源需要,P4阻塞等待。
    P4请求资源Request4(3,3,0)不允许。

    ④ T2之后的T3时刻P0请求资源Request0(0,2,0)是否允许?

    Request0(0,2,0)≤Need0(7,4,3);
    Request0(0,2,0)≤Available(2,3,0);
    系统暂时先假定可为P0分配资源,并修改有关数据,如下图所示:

    进行安全性检查:可用资源Available(2,1,0)已不能满足任何进程的需要,故系统进入不安全状态,此时系统不分配资源。

    程序结构

    程序共有以下五个部分:

    (1).初始化init():输入进程数量、资源种类、资源可利用量、进程资源已分配量、进程最大需求量
    (2).当前安全性检查safe():用于判断当前状态安全
    (3).银行家算法bank():进行银行家算法模拟实现的模块
    (4).显示当前状态show():显示当前资源分配详细情况
    (5).主程序main():逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行

    四、实验代码

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3  
      4 #define False 0
      5 #define True 1
      6  
      7 /********主要数据结构********/
      8 char NAME[100]={0};//资源的名称
      9 int Max[100][100]={0};//最大需求矩阵
     10 int Allocation[100][100]={0};//系统已分配矩阵
     11 int Need[100][100]={0};//还需要资源矩阵
     12 int Available[100]={0};//可用资源矩阵
     13 int Request[100]={0};//请求资源向量    
     14 int Work[100]={0};//存放系统可提供资源量 
     15 int Finish[100]={0}; //标记系统是否有足够的资源分配给各个进程 
     16 int Security[100]={0};//存放安全序列
     17  
     18 int M=100;//进程的最大数
     19 int N=100;//资源的最大数
     20  
     21 /********初始化数据:输入进程数量、资源种类、各种资源可利用数量、
     22 各进程对资源最大需求量、各进程的资源已分配数量等。********/
     23 void init()
     24 {
     25     /* m为进程个数,即矩阵行数,n为资源种类,即矩阵列数。*/
     26     int i,j,m,n;
     27     int number,flag;
     28     char name;//输入资源名称
     29     int temp[100]={0};//统计已经分配的资源
     30     //输入系统资源数目及各资源初试个数 
     31     printf("系统可用资源种类为:");
     32     scanf("%d",&n);
     33     N=n;
     34     for(i=0;i<n;i++)
     35     {
     36         printf("资源%d的名称:",i);
     37         fflush(stdin);  //清空输入流缓冲区的字符,注意必须引入#include<stdlib.h>头文件
     38         scanf("%c",&name);
     39         NAME[i]=name;
     40         printf("资源%c的初始个数为:",name);    
     41         scanf("%d",&number);
     42         Available[i]=number;
     43     }
     44     
     45     //输入进程数及各进程的最大需求矩阵 
     46     printf("
    请输入进程的数量:");    
     47     scanf("%d",&m);
     48     M=m;
     49     printf("请输入各进程的最大需求矩阵的值[Max]:
    ");
     50     do{
     51         flag = False;
     52         for(i=0;i<M;i++)
     53             for(j=0;j<N;j++)
     54             {
     55                 scanf("%d",&Max[i][j]);
     56                 if(Max[i][j]>Available[j])
     57                     flag = True;                
     58             }
     59         if(flag)
     60             printf("资源最大需求量大于系统中资源最大量,请重新输入!
    ");                                
     61     } while(flag);
     62     
     63             
     64     //输入各进程已经分配的资源量,并求得还需要的资源量 
     65     do{
     66         flag=False;
     67         printf("请输入各进程已经分配的资源量[Allocation]:
    ");
     68         for(i=0;i<M;i++)
     69         {
     70             for(j=0;j<N;j++)
     71               {
     72                 scanf("%d",&Allocation[i][j]);
     73                 if(Allocation[i][j]>Max[i][j])  
     74                     flag=True;                
     75                 Need[i][j]=Max[i][j]-Allocation[i][j];
     76                 temp[j]+=Allocation[i][j];//统计已经分配给进程的资源数目
     77               }
     78         }
     79         if(flag)
     80             printf("分配的资源大于最大量,请重新输入!
    ");        
     81     }while(flag);
     82     
     83     //求得系统中可利用的资源量 
     84     for(j=0;j<N;j++)
     85         Available[j]=Available[j]-temp[j];
     86 }
     87  
     88 /********显示资源分配矩阵********/
     89 void showdata()
     90 {
     91     int i,j;
     92     printf("*************************************************************
    ");
     93     printf("系统目前可用的资源[Available]:
    ");
     94     for(i=0;i<N;i++)
     95         printf("%c  ",NAME[i]);
     96     printf("
    ");
     97     for(j=0;j<N;j++)
     98         printf("%d  ",Available[j]);
     99     printf("
    ");
    100     printf("系统当前的资源分配情况如下:
    ");
    101     printf("            Max        Allocation    Need
    ");
    102     printf("进程名     ");
    103     //输出与进程名同行的资源名,Max、Allocation、Need下分别对应 
    104     for(j=0;j<3;j++){
    105         for(i=0;i<N;i++)
    106             printf("%c  ",NAME[i]);
    107         printf("     ");
    108     }
    109     printf("
    ");
    110     //输出每个进程的Max、Allocation、Need 
    111     for(i=0;i<M;i++){
    112         printf(" P%d        ",i);
    113         for(j=0;j<N;j++)
    114             printf("%d  ",Max[i][j]);
    115         printf("     "); 
    116         for(j=0;j<N;j++)
    117             printf("%d  ",Allocation[i][j]);
    118         printf("     "); 
    119         for(j=0;j<N;j++)
    120             printf("%d  ",Need[i][j]);
    121         printf("
    ");
    122     }
    123 }
    124  
    125 /********尝试分配资源********/
    126 int test(int i) //试探性的将资源分配给第i个进程 
    127 { 
    128     for(int j=0;j<N;j++)
    129     {
    130         Available[j]=Available[j]-Request[j];
    131         Allocation[i][j]=Allocation[i][j]+Request[j];
    132         Need[i][j]=Need[i][j]-Request[j];
    133     }
    134     return True;
    135 }
    136  
    137 /********试探性分配资源作废********/
    138 int Retest(int i) //与test操作相反 
    139 { 
    140     for(int j=0; j<N; j++)
    141     {
    142         Available[j] = Available[j] + Request[j];
    143         Allocation[i][j] = Allocation[i][j] - Request[j];
    144         Need[i][j] = Need[i][j] + Request[j];
    145     }
    146     return True;
    147 }
    148  
    149 /********安全性算法********/
    150 int safe()
    151 {
    152     int i,j,k=0,m,apply;
    153     //初始化work 
    154     for(j=0;j<N;j++)
    155         Work[j] = Available[j];
    156     //初始化Finish 
    157     for(i=0;i<M;i++) 
    158         Finish[i] = False;
    159     //求安全序列 
    160     for(i=0;i<M;i++){ 
    161         apply=0;
    162         for(j=0;j<N;j++){
    163             if(Finish[i]==False && Need[i][j]<=Work[j])
    164             {   
    165                 apply++;
    166                 //直到每类资源尚需数都小于系统可利用资源数才可分配
    167                 if(apply==N)
    168                 {  
    169                     for(m=0;m<N;m++)
    170                         Work[m]=Work[m]+Allocation[i][m];//更改当前可分配资源
    171                     Finish[i]=True;
    172                     Security[k++]=i;
    173                     i=-1; //保证每次查询均从第一个进程开始        
    174                 }
    175             }
    176         }
    177     }
    178     
    179     for(i=0;i<M;i++){
    180         if(Finish[i]==False){
    181             printf("系统不安全
    ");//不成功系统不安全
    182             return False;
    183         }
    184     }
    185     printf("系统是安全的!
    ");//如果安全,输出成功
    186     printf("存在一个安全序列:");
    187     for(i=0;i<M;i++){//输出运行进程数组
    188         printf("P%d",Security[i]);
    189         if(i<M-1) 
    190             printf("->");
    191     }
    192     printf("
    ");
    193     return True;
    194 }
    195  
    196 /********利用银行家算法对申请资源进行试分********/
    197 void bank()
    198 {
    199     int flag = True;//标志变量,判断能否进入银行家算法的下一步 
    200     int i,j;
    201  
    202     printf("请输入请求分配资源的进程号(0-%d):",M-1); 
    203     scanf("%d",&i);//输入须申请资源的进程号
    204     
    205     printf("请输入进程P%d要申请的资源个数:
    ",i);
    206     for(j=0;j<N;j++)
    207     {
    208         printf("%c:",NAME[j]);
    209         scanf("%d",&Request[j]);//输入需要申请的资源
    210     }
    211     
    212     //判断银行家算法的前两条件是否成立 
    213     for (j=0;j<N;j++)
    214     {
    215         if(Request[j]>Need[i][j])//判断申请是否大于需求,若大于则出错
    216         { 
    217             printf("进程P%d申请的资源大于它需要的资源",i);
    218             printf("分配不合理,不予分配!
    ");
    219             flag = False;
    220             break;
    221         }
    222         else 
    223         {
    224             if(Request[j]>Available[j])//判断申请是否大于当前可分配资源,若大于则出错
    225             {                         
    226                 printf("进程%d申请的资源大于系统现在可利用的资源",i);
    227                 printf("
    ");
    228                 printf("系统尚无足够资源,不予分配!
    ");
    229                 flag = False;
    230                 break;
    231             }
    232         }
    233     }
    234     //前两个条件成立,试分配资源,寻找安全序列 
    235     if(flag) {
    236         test(i); //根据进程需求量,试分配资源 
    237         showdata(); //根据进程需求量,显示试分配后的资源量 
    238         if(!safe()) //寻找安全序列
    239         {
    240             Retest(i);
    241             showdata();
    242         }
    243     }
    244 }
    245  
    246  
    247 int main()//主函数
    248 {    
    249     char choice;
    250     printf("	---------------------------------------------------
    ");
    251     printf("	||                                               ||
    ");
    252     printf("	||               银行家算法的实现                ||
    ");
    253     printf("	||                                               ||
    ");
    254     printf("	||                                               ||
    ");
    255     printf("	||                     在此输入个人姓名:******  ||
    ");
    256     printf("	||                                               ||
    ");
    257     printf("	---------------------------------------------------
    ");
    258     init();//初始化数据
    259     showdata();//显示各种资源
    260     //用银行家算法判定系统当前时刻是否安全,不安全就不再继续分配资源 
    261     if(!safe()) exit(0);
    262     
    263     do{
    264         printf("*************************************************************
    ");
    265         printf("
    ");
    266         printf("
    ");
    267         printf("	-------------------银行家算法演示------------------
    ");
    268         printf("                     R(r):请求分配   
    ");    
    269         printf("                     E(e):退出       
    ");
    270         printf("	---------------------------------------------------
    ");
    271         printf("请选择:");
    272         fflush(stdin);  //清空输入流缓冲区的字符,注意必须引入#include<stdlib.h>头文件
    273         scanf("%c",&choice);
    274         switch(choice)
    275         {
    276             case 'r':
    277             case 'R':
    278                 bank();break;            
    279             case 'e':
    280             case 'E':
    281                 exit(0);
    282             default: printf("请正确选择!
    ");break;
    283         }
    284     } while(choice);
    285 }
    286  
    287  
  • 相关阅读:
    Silverlight入门:第四部分 数据绑定
    [Silverlight入门系列]使用MVVM模式(6):使用Behavior
    Silverlight入门:第二部分 定义界面布局和导航
    [Silverlight入门系列]使用MVVM模式(2):集合Model /ObservableCollection/ICollectionView
    建立可扩展的silverlight应用框架 step5:整理Module
    Silverlight入门:第六部分 美化用户界面的样式与模板
    [Silverlight入门系列]使用MVVM模式(7):ViewModel的INotifyPropertyChanged接口实现
    Silverlight WCF RIA服务(五)使用SL商业应用模板
    Silverlight WCF RIA服务(四)如何添加和移除RIA Services Link
    Asymptote 学习记录(3) 画赵爽弦图练习
  • 原文地址:https://www.cnblogs.com/GLory-LTF/p/15035359.html
Copyright © 2011-2022 走看看