操作系统实验:银行家算法(C++)

(新人上路,C++基本新手,用了很多for循环以及goto)

 

一、实验目的

死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂 上所讲授的知识的理解。

二、实验要求 

设计有 n 个进程共享 m 个系统资源的系统,进程可动态的申请和释放资源,系 统按各进程的申请动态的分配资源。 系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用 户观察和分析; 

三、数据结构 

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

2.最大需求矩阵 Max,这是一个 n×m 的矩阵,它定义了系统中 n 个进程中的每一 个进程对 m 类资源的最大需求。如果 Maxij=k,表示进程 i 需要 Rj 类资源 的最大数目为 k

3.分配矩阵 Allocation,这是一个 n×m 的矩阵,它定义了系统中的每类资源当前 一分配到每一个进程的资源数。如果 Allocationij=k,表示进程 i 当前已经 分到 Rj 类资源的数目为 kAllocation i表示进程 i 的分配向量,有矩阵 Allocation7 的第 i 行构成。

4.需求矩阵 Need,这是一个 n×m 的矩阵,用以表示每个进程还需要的各类资源的 数目。如果 Needij=k,表示进程 i 还需要 Rj 类资源 k 个,才能完成其任 务。Need i表示进程 i 的需求向量,由矩阵 Need 的第 i 行构成。 上述三个矩阵间存在关系:Needij=Maxij-Allocationij);

四、银行家算法 

参考教材上银行家算法描述。

五、安全性算法 

1.设置两个向量。

Work:它表示系统可提供给进程继续运行的各类资源数目,它包含 m 个元素, 开始执行安全性算法时,Work = Available

Finish:它表示系统是否有足够的资源分配给进程,使之运行完成,开始 FinishI=false;当有足够资源分配给进程 Pi 时,令 Finishi=true

2.从进程集合中找到一个能满足下述条件的进程。

Finishi= = false

Need i work

如找到则执行步骤 3;否则,执行步骤 4

3.当进程 Pi 获得资源后,可顺利执行直到完成,并释放出分配给它的资源,故应

执行

Work = work + Allocation i

Finishi=true;转向步骤 2

4.若所有进程的 Finishi)都为 true,则表示系统处于安全状态;否则,系统处于 不安全状态

六、实验方案


七、实验代码

#include<iostream>
using namespace std;

int n,m;                                                        //n个进程,m种资源
int MAX[10][10];                                                //最大值矩阵
int NEED[10][10];                                                //需求矩阵
int ALL[10][10];                                                //保持矩阵
int AVA[10];                                                    //可用资源
int REQ[10][10];                                                //申请资源
bool finish[10];                                                //安全算法所需
int work[10];

void show(){                                                    //输出矩阵
    cout<<"进程名        Max          Need           Allocation            Available        完成情况\n";
    for(int i=0;i<n;i++){
        cout<<"p"<<i<<"      ";
        int count=0;
        for(int j=0;j<m;j++)cout<<MAX[i][j]<<" ";
        cout<<"        ";
        for(int j=0;j<m;j++)cout<<NEED[i][j]<<" ";
        cout<<"        ";
        for(int j=0;j<m;j++)cout<<ALL[i][j]<<" ";
        cout<<"        ";
        for(int j=0;j<m;j++)cout<<work[j]<<" ";
        cout<<"        ";
        cout<<finish[i];
        cout<<endl;
    }
}
int safe(){
    int p[10];                                                    //保存安全序列
    int l=0;
    for(int i=0;i<m;i++)work[i]=AVA[i];                            //安全算法先将AVA赋给work
    for(int i=0;i<n;i++)finish[i]=false;                        //表示进程是否已执行
    int count2=0;                                                //控制遍历次数
    int count1=0;                                                //与n对比,相等为安全
    X:for(int i=0;i<n;i++){
        int count=0;                                            //控制NEED与work比较
        for(int j=0;j<m;j++)if(NEED[i][j]<=work[j])count++;
        if(!finish[i]&&count==m){
            for(int j=0;j<m;j++)work[j]=work[j]+ALL[i][j];
            finish[i]=true;                                        //表示已运行
            p[l++]=i;                                            
            count++;
            count1++;
            show();
        }
    }
    if(count1==n){
        cout<<"\n系统安全\n\n安全序列为:";
        cout<<'p'<<p[0];
        for(int i=1;i<l;i++)cout<<"->"<<'p'<<p[i];                //输出安全序列
        cout<<endl;
        return 1;
    }
    else{
        count2++;
        if(count2==3){
            cout<<"\n系统不安全\n";
            return 0;                                            //重复遍历3次未安全则不安全
        }
        goto X;                                                    //重复遍历
    }    
}
int main(){
    cout<<"请输入进程数(<=10):\n";
    cin>>n;
    cout<<"请输入资源种类数(<=10):\n";
    cin>>m;
    cout<<"请输入MAX(最大)矩阵("<<n<<"行"<<m<<"列)\n";
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>MAX[i][j];
        }
    }
    cout<<"请输入ALL(保持)矩阵("<<n<<"行"<<m<<"列)\n";
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>ALL[i][j];
            NEED[i][j]=MAX[i][j]-ALL[i][j];
            if(NEED[i][j]<0){
                cout<<"输入错误,请重新输入:\n";
                int m;
                cin>>m;
                ALL[i][j]=m;
                NEED[i][j]=MAX[i][j]-ALL[i][j];
            }
        }
    }
    cout<<"请输入"<<m<<"种资源现有的数目:\n";
    for(int i=0;i<m;i++)cin>>AVA[i];
    if(!safe()){
        cout<<"\n输入的初始序列不安全,进程结束\n";
        system("pause");
        return 0;
    }
    Y:cout<<"\n请输入一个来自0到"<<n<<"进程的请求,请求"<<m<<"种资源,各资源得数目(先输入进程(数字),再输入资源):\n";
    int x;
    cin>>x;
    for(int i=0;i<m;i++)cin>>REQ[x][i];    
    int count=0;
    for(int i=0;i<m;i++){
        if(REQ[x][i]<=NEED[x][i])count++;
    }
    if(count!=m){cout<<"\n输入有误,超过该进程的需求,请重新输入\n";goto Y;}
    else{
        for(int i=0;i<m;i++){
            AVA[i]=AVA[i]-REQ[x][i];
            ALL[x][i]=ALL[x][i]+REQ[x][i];
            NEED[x][i]=NEED[x][i]-REQ[x][i];
        }
        if(safe()){
            cout<<"\n系统安全,可以分配\n";
            for(int i=0;i<m;i++){
                AVA[i]=AVA[i]+REQ[x][i];
                ALL[x][i]=ALL[x][i]-REQ[x][i];
                NEED[x][i]=NEED[x][i]+REQ[x][i];
            }
        }
        else {
            cout<<"\n系统不安全,不予分配\n";
            for(int i=0;i<m;i++){
                AVA[i]=AVA[i]+REQ[x][i];
                ALL[x][i]=ALL[x][i]-REQ[x][i];
                NEED[x][i]=NEED[x][i]+REQ[x][i];
            }
        }
        int sf;
        cout<<"\n是否再次尝试?请输入0(否)1(是):\n";
        cin>>sf;
        if(sf)goto Y;
    }
    system("pause");
    return 0;
}

  • 代码思路
  1. 输出函数:

每次运行输出进程名及其资源得需,完成情况。

  1. 安全性算法函数:

(1)先用AVA数组初始化work数组(用work不会影响AVA),设置数组p[10]用来输出安全序列,并让finish数组全部为false,代表所有进程未执行(执行后变为true)。

(2)循环遍历进程,如果一个进程finish[i]为false且NEED[i][j]都小于work[j],则令finish[i]变为true(表示已运行),p[l++]记录进程,计数器1加一,调用输出函数。

(3)判断计数器1是否等于n(是否全部进程都完成),若相等,表示安全,调用p[]数组输出安全序列,返回整数1。

若不相等,计数器2加一。若计数器2等于3(重复遍历三次未成功),表示不安全,返回整数0;若不为3,则返回(2)中循环重复遍历。

  1. 银行家算法(主函数):
  1. 输入进程数n,资源数m,以及各类矩阵,调用安全性算法,查看是否安全,安全则输出运行情况及安全序列;不安全则输数该进程初始状态不安全并结束进程。
  2. 输入x表示进程,循环输入REQ[x][j],表示进程请求资源。判断资源是否大于其需求NEED[x][j]:若大于,返回(2)重新输入;若不大于,执行下一步。
  3. 分配资源,AVA,ALL,NEED矩阵各值变化。
  4. 调用安全性算法。安全则可以分配,输出运行情况及安全序列;不安全则不允分配。
  • 运行情况

    1.输入阶段:

2.检查安全性:

3.银行家算法:

(1)p1申请 1 2 0 0

(2)p2申请 1 0 1 0

(3)p1申请 0 0 1 2

  • 17
    点赞
  • 223
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值