操作系统:银行家算法

简介: 操作系统:银行家算法


银行家算法

一、实验目的

1、理解银行家算法。

2、掌握进程安全性检查的方法及资源分配方法。

二、实验要求与内容、过程与结果

1、将图5-1补充完整,画出银行家算法的流程图。

图5-1 银行家算法的流程图

2、将图5-2补充完整,画出安全性检查算法的流程图。

图5-2 安全性检查算法的流程图

3、编写补充完整模拟银行家算法程序sy-5.cpp,并以下面给出的例子来验证编写程序的正确性。要求记录程序运行过程和结果。

例子:某系统有A、B、C、D 4类资源共5个进程(P0,P1,P2,P3、P4)共享,各进程对资源的需求的分配情况如表5-1所示。

现在系统中A、B、C、D 4类资源分别还剩下1、5、2、0个,请按银行家算法回答下列问题:

① 现在系统是否处于安全状态?

答:系统当前处于安全状态,安全序列为:0->2->3->4->1。

② 如果现在进程P1提出资源请求(0、4、2、0),系统能否满足它的请求?

答:能满足。

模拟银行家算法程序sy-5.cpp:

#include <iostream>
using namespace std;
int Available[100];   //可利用资源数组
int Max[50][100];   //最大需求矩阵
int Allocation[50][100];   //分配矩阵
int Need[50][100];      //需求矩阵
int Request[50][100];
int Finish[50];
int p[50];
int m,n;        //m个进程,n个资源
int IsSafe( )   //系统安全性检查
{
int i,j,L=0;
int Isfind=1;
    int Work[100];
    for(i=0; i<n; i++)
           Work[i] = Available[i]    ; //建立Available副本Work,即对Work初始化
    for(i=0; i<m; i++)
            Finish[i] = 0        ;         // 对Finish进行初始化
    while(L<m&&Isfind)
    {
        Isfind=0;
for(i=0; i<m; i++)
      {
          if (Finish[i]==1) continue;   
          else
          {
               for(j=0; j<n; j++)
                   if(Need[i][j]>Work[j]) break;
            if(j==n)     
            {
                Finish[i]=    1    ;       //表示进程i能结束
                for(int k=0; k<n; k++)
                      Work[k] += Allocation[i][k] ; //进程i能结束,释放资源
                p[L++]=i;
        Isfind=1;
                if(L==m)
                    break;
             }
        }
      }
    }
    if (     L == m   )   //判定是否存在安全系列。提示:判定L与m值的关系
    {
        cout<<"系统是安全的!"<<"安全系列是:"<<endl;
        for(i=0; i<m; i++)
        {
            cout<<p[i];
            if(i<m-1) cout<<"-->";
        }
        cout<<endl;
        return 1;
    }
    else
    {
        cout<<"系统处于不安全状态!";
        return 0;
    }
}
int main()
{
    int i,j,mi,flag=1;
    cout<<"输入进程数目:\n";
    cin>>m;
    cout<<"输入资源的种类数:\n";
    cin>>n;
    cout<<"输入每个进程最多所需要的各资源数,按照"<<m<<"×"<<n<<"矩阵输入!\n";
    for(i=0; i<m; i++)
        for (j=0; j<n; j++)
            cin>>Max[i][j];
    cout<<"输入每个进程已分配的各资源数,也按照"<<m<<"×"<<n<<"矩阵输入!\n";
    for(i=0; i<m; i++)
    {
        for (j=0; j<n; j++)
        {
            cin>>Allocation[i][j];
            Need[i][j]=Max[i][j]-Allocation[i][j];
            if (Need[i][j]<0)
            {
  cout<<"你输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数错误,请重新输入!\n";
                j--;
                continue;
            }
        }
    }
    cout<<"请输入各个资源现有的数目:\n";
    for(i=0; i<n; i++)
        cin>>Available[i];
    if(IsSafe()!=1)  
        return 0;
    while(1)
    {
        flag=1;
        cout<<"输入要申请资源的进程号(第一个进程号为0,以此类推):\n";
        cin>>mi;
        cout<<"输入该进程所请求各资源的数量:\n";
        for(i=0; i<n; i++)
            cin>>Request[mi][i];
        for(i=0; i<n&&flag; i++)
        {
            if (   Need[mi][i]<Request[mi][i]       )   
            {
               cout <<"进程P"<<mi<<"的资源请求数超过进程的需求量,拒绝分配!\n";
                flag=0;
                break;
            }
            if (    Available[i]<Request[mi][i]     )
            {
             cout <<"进程P"<<mi<<"的请求数超过了系统所可用的资源数,拒绝分配!\n";
                flag=0;
                break;
            }
        }
        if(flag)
        {
            for(i=0; i<n; i++) //试探分配资源给进程mi
            {
                Available[i]-=    Request[mi][i]       ;
                Allocation[mi][i]+=Request[mi][i];
                Need[mi][i]-=   Request[mi][i]        ;
            }
            if (    IsSafe() == 1     ) cout<<"同意分配请求!\n" ;  // 提示:调用安全性检测函数
            else
            {
                cout<<"资源分配请求被拒绝!\n";
                for(i=0; i<n; i++) //恢复进程mi以前的资源分配状态
                {
                    Available[i]+=Request[mi][i];
                    Allocation[mi][i]-=   Request[mi][i]    ;
                    Need[mi][i]+=Request[mi][i];
                }
            }
        }
        for(i=0; i<m; i++)
            Finish[i]=0;
        char YesNo;
        while(1)
        {
            cout<<"继续请求资源分配请按 y或Y ,结束程序请按 n或N :";
            cin>>YesNo;
            cout<<endl;
            if (YesNo=='y'||YesNo=='Y') break;
            else if (YesNo=='n'||YesNo=='N') return 0;
        }
    }
}

本程序是一个简单的银行家算法实现,可以模拟对多进程的资源分配管理。

程序功能:

1.输入进程数目和资源种类数目; 2.输入每个进程最多需要的各资源的数量和已经分配的各资源的数量,计算出每个进程还需要的各个资源数量; 3.输入各个资源当前可用的数量; 4.进行系统安全性检查,判断系统是否处于安全状态; 5.根据用户输入,模拟对进程的资源请求分配; 6.如果分配后系统仍然处于安全状态,同意分配请求,否则拒绝分配请求; 7.根据用户输入,判断是否退出程序。

程序结构:

程序主体部分由主函数实现,包含了系统安全性检查函数IsSafe()和分配资源请求的处理部分。

主要变量:

1.Available[]:可用资源数组,记录每个资源当前可用的数量。 2.Max[][]:进程最多需要各资源的的数量。 3.Allocation[][]:各进程已分配的各资源数量。 4.Need[][]:各进程还需要的各资源数量。 5.Request[][]:进程的资源请求。 6.Finish[]:标记进程是否执行完毕。 7.p[]:存储安全序列。

程序运行流程:

1.用户输入进程数目和资源种类数目; 2.用户输入每个进程最多需要的各资源的数量和已经分配的各资源的数量,计算出每个进程还需要的各个资源数量; 3.用户输入各个资源当前可用的数量; 4.调用IsSafe()函数,判断系统是否处于安全状态; 5.用户输入资源分配请求,根据银行家算法进行资源分配请求处理; 6.如果处理后系统处于安全状态,输出同意分配请求信息,否则输出拒绝分配请求信息; 7.询问用户是否继续,并根据用户输入继续或结束程序。

程序分析:

银行家算法能保证系统安全性,即能够防止死锁和饥饿的情况发生。因此,在本程序中,系统安全性检查是必不可少的。IsSafe()函数的具体实现过程为:

1.将Available数组复制到Work数组中; 2.将所有进程的Finish数组置为0; 3.在未处理完所有进程的情况下,遍历所有进程,寻找可以结束的进程(即进程的Need数组小于等于Work数组); 4.如果找到可以结束的进程,将该进程标记为已结束(Finish数组置为1),将该进程所占用的资源释放(即Work数组增加Allocation数组中该进程所占用的资源数量),将该进程的进程号存储到安全序列p[]数组中,此时需要重新遍历所有进程; 5.如果无法找到可以结束的进程,则说明系统不安全。

程序中分配资源请求的处理部分的具体实现过程为:

1.用户输入进程号和资源请求数量; 2.判断资源请求是否超过进程的需求量,如果超过则拒绝分配请求并进行下一次请求; 3.判断资源请求是否超过系统可用资源数量,如果超过则拒绝分配请求并进行下一次请求; 4.对进程进行试探性分配,如果分配后系统处于安全状态,则同意分配请求,否则拒绝分配请求,将资源分配状态恢复到进程请求前的状态; 5.询问用户是否继续进行资源请求分配,并根据用户输入决定是否继续。

目录
相关文章
|
1月前
|
算法 调度 UED
探索操作系统的心脏:调度算法的奥秘与影响
【10月更文挑战第9天】 本文深入探讨了操作系统中至关重要的组件——调度算法,它如同人体的心脏,维持着系统资源的有序流动和任务的高效执行。我们将揭开调度算法的神秘面纱,从基本概念到实际应用,全面剖析其在操作系统中的核心地位,以及如何通过优化调度算法来提升系统性能。
|
20天前
|
算法 大数据 Linux
深入理解操作系统之进程调度算法
【10月更文挑战第24天】本文旨在通过浅显易懂的语言,带领读者深入了解操作系统中的进程调度算法。我们将从进程的基本概念出发,逐步解析进程调度的目的、重要性以及常见的几种调度算法。文章将通过比喻和实例,使复杂的技术内容变得生动有趣,帮助读者建立对操作系统进程调度机制的清晰认识。最后,我们还将探讨这些调度算法在现代操作系统中的应用和发展趋势。
|
1月前
|
算法 调度 UED
深入理解操作系统的进程调度算法
【10月更文挑战第7天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。它不仅影响系统的性能和用户体验,还直接关系到资源的合理分配。本文将通过浅显易懂的语言和生动的比喻,带你一探进程调度的秘密花园,从最简单的先来先服务到复杂的多级反馈队列,我们将一起见证算法如何在微观世界里编织宏观世界的和谐乐章。
|
1月前
|
边缘计算 算法 调度
探究操作系统的心脏:调度算法的进化与影响
【10月更文挑战第2天】 本文深入探讨了操作系统中核心组件——调度算法的历史演变、关键技术突破及其对现代计算的影响。通过详细回顾从单任务到多任务、实时系统及分布式计算环境下调度算法的发展,文章揭示了这些算法如何塑造我们的数字世界,并对未来的趋势进行了展望。不同于传统的摘要,本文特别聚焦于技术细节与实际应用的结合点,为读者提供一幅清晰的技术演进蓝图。
46 4
|
1月前
|
算法 调度 UED
探索操作系统的心脏:进程调度算法
【9月更文挑战第32天】在数字世界的每一次心跳中,都隐藏着一个不为人知的英雄——进程调度算法。它默默地在后台运作,确保我们的命令得到快速响应,应用程序平稳运行。本文将带你走进操作系统的核心,一探进程调度的奥秘,并通过代码示例揭示其背后的智慧。准备好跟随我一起深入这趟技术之旅了吗?让我们开始吧!
|
2月前
|
算法 调度
操作系统的心脏:深入解析进程调度算法
本文旨在深入探讨现代操作系统中的核心功能之一——进程调度。进程调度算法是操作系统用于分配CPU时间片给各个进程的机制,以确保系统资源的高效利用和公平分配。本文将详细介绍几种主要的进程调度算法,包括先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)以及优先级调度(PS)。我们将分析每种算法的基本原理、优缺点及其适用场景。同时,本文还将讨论多级反馈队列(MFQ)调度算法,并探讨这些算法在实际应用中的表现及未来发展趋势。通过深入解析这些内容,希望能够为读者提供对操作系统进程调度机制的全面理解。
|
2月前
|
存储 算法 前端开发
深入理解操作系统:进程调度与优先级队列算法
【9月更文挑战第25天】在操作系统的复杂世界中,进程调度是维持系统稳定运行的核心机制之一。本文将深入探讨进程调度的基本概念,分析不同的进程调度算法,并着重介绍优先级队列算法的原理和实现。通过简洁明了的语言,我们将一起探索如何优化进程调度,提高操作系统的效率和响应速度。无论你是计算机科学的初学者还是希望深化理解的专业人士,这篇文章都将为你提供有价值的见解。
|
2月前
|
人工智能 算法 大数据
探究操作系统的心脏:调度算法的进化与影响
本文深入探讨了操作系统中核心组件——调度算法的发展及其对系统性能的影响。通过分析先来先服务、短作业优先、时间片轮转等传统调度算法,阐述了它们的原理和优缺点。同时,讨论了现代调度算法如多级队列和优先级调度在提高系统响应速度和处理能力方面的作用。文章还探讨了实时系统中的调度挑战,以及如何通过优化调度策略来满足不同应用场景下的性能需求。
|
2月前
|
机器学习/深度学习 算法 物联网
探究操作系统的心脏:调度算法的演变与优化
本文旨在深入探讨操作系统中核心组件——调度算法的发展脉络与优化策略。通过分析从单任务到多任务、实时系统的演进过程,揭示调度算法如何作为系统性能瓶颈的解决关键,以及在云计算和物联网新兴领域中的应用前景。不同于传统摘要,本文将注重于概念阐释与实例分析相结合,为读者提供直观且全面的理解视角。
|
2月前
|
算法 调度 UED
深入理解操作系统的调度算法
【9月更文挑战第22天】本文通过深入浅出的方式,介绍了操作系统中的核心概念——调度算法。文章首先解释了调度算法的基本定义和重要性,然后详细分析了先来先服务(FCFS)、短作业优先(SJF)以及时间片轮转(RR)三种常见的调度算法。每种算法都配有简单的代码示例,帮助读者更好地理解其工作原理。最后,文章探讨了这些调度算法在现代操作系统中的应用及其优缺点,旨在为读者提供对操作系统调度机制的全面认识。