操作系统课程设计——银行家算法改进实现

前言

hnust操作系统课程设计,其他题目较为简单,可参考其他优秀博主的文章,这里仅介绍两道题

  • 简单 shell 命令行解释器的设计与实现
  • 银行家算法改进实现

本篇为银行家算法改进实现

白嫖容易,创作不易,若大家认为有用,学到东西,不妨点个赞

博客原创,转载请注明出处

附上另一篇博客链接:简单 shell 命令行解释器的设计与实现

仅用于学习,如有侵权,请联系删除

注意:程序中仍有不足点,例如并未实现多个进程同时请求时需要选择调度其中一个,有兴趣的同学可以自行更改

实验题目

将银行家算法改进为动态不断请求形式

实验目的

本实验主要目的在于进一步理解真正的银行家算法,并且处理实际意义情况下的银行家算法,将其改进为动态情况。

设计内容和要求

要设计的功能必须支持以下情况:

(1)首先要设置好总资源数量;

(2)新进程申请时需要输入其max(claim)资源数量(必须小于总资源数);

(3)新进程申请尝试分配后,更新状态,不成立则阻塞,成立则分配;

(4)老进程可能再次申请;

(5)老进程申请后需要判定结束,若结束则需判定阻塞的进程是否能转为就绪态;

(6)静态申请改为动态申请,结束需要回收数组;

(7)阻塞队列中可以加入算法;

总体设计

流程图:

在这里插入图片描述

算法步骤:

使用了C++的vector的一些方法,若不明白可以自行查阅资料

首先是一个无限循环。

  1. 首先在main函数中,我们需要设置一个无限循环,不断让用户进程申请

  2. 输入进程编号后检测是否为老进程,若不是则需要输入最大申请资源数

    printf("请输入需要申请的进程编号:\n");
    cin >> num;
    res.number = num;
    vector<int>::iterator iter=find(vec.begin(),vec.end(),num);
    if(iter==vec.end())//未找到
    {
        cout << "未查找到老进程P" << num << endl;
        vec.push_back(num);
        printf("请输入P%d进程所需资源总数(claim):\n",num);
        cin >> res.a >> res.b >> res.c;
        claim.push_back(res);
        max_claim.push_back(res);
    }
    
  3. 输入此次申请资源数

  4. 检测是否会阻塞,若阻塞则加入阻塞队列,否则进行分配资源

    if(checkBlock(num))//checkBlock检测是否会阻塞
    {
        cout << "允许P" << num << "进程分配资源" << endl;
        nowClaim = findClaim();//查找当前进程最大申请量
        if(safeQueue(nowClaim)) flag=true; //某进程结束,释放资源
        else 
        {
            if(block.size()==0) flag=false;//未释放资源且阻塞队列为空则重新输入(避免阻塞队列中取出一个后就不管剩下阻塞的进程了)
        }
        cout << "当前资源剩余量:" << RESOURCE[0] << "  " << RESOURCE[1] << "  " << RESOURCE[2] << endl;
    }
    else //阻塞
    {
        res.a = request[0];
        res.b = request[1];
        res.c = request[2];
        block.push_back(res);
    }
    
  5. 分配资源时判断是否进程结束(达到最大进程申请资源数),若满足则释放资源,否则继续输入新进程申请

    bool safeQueue(int nowClaim)//分配资源
    {
    	//允许分配资源,调整资源值
    	if(flag)//表示阻塞队列中的一个进程转为就绪态进行分配资源
        {
            request[0] = block[0].a;
            request[1] = block[0].b;
            request[2] = block[0].c;
            std::vector<resource>::iterator it4 = block.begin();
            block.erase(it4);//将其从阻塞队列中删除
        }
    	for(int j=0;j<3;j++) RESOURCE[j]-=request[j];
    	claim[nowClaim].a-=request[0];
    	claim[nowClaim].b-=request[1];
    	claim[nowClaim].c-=request[2];
    	if(claim[nowClaim].a==0&&claim[nowClaim].b==0&&claim[nowClaim].c==0)
        {
            cout << "进程P" << claim[nowClaim].number << "结束,释放资源" << endl;
            std::vector<int>::iterator it = vec.begin();
            std::vector<resource>::iterator it1 = claim.begin();
            std::vector<resource>::iterator it2 = max_claim.begin();
            it=vec.begin()+nowClaim;
            it1=claim.begin()+nowClaim;
            it2=max_claim.begin()+nowClaim;
            vec.erase(it);
            claim.erase(it1);//表示释放资源,该进程结束
            RESOURCE[0]+=max_claim[nowClaim].a;
            RESOURCE[1]+=max_claim[nowClaim].b;
            RESOURCE[2]+=max_claim[nowClaim].c;
            max_claim.erase(it2);
            return true;
        }
    	else return false;
    }
    
  6. 若释放资源,则需要判断阻塞队列是否有满足的进程,将所有满足的进程都分配资源,并重复上述检测是否结束的步骤

    else//表示上次分配资源后有进程结束释放资源,需要检测阻塞队列
    {
        if(!allocBlock())
        {
            flag = false;//如果阻塞队列没有符合进程则下次不用检测阻塞队列,反之下次继续
            continue;
        }
        cout << "P" << num << "进程由阻塞态转为就绪态" << endl;
    }
    

实验结果分析

由上述结果可以看出,实现了,遇到老进程再次申请资源时,会判断是否满足该进程最大申请量(max),若满足则表示进程可以结束,释放资源,每次释放资源后,检查阻塞队列中是否有满足条件的进程,若满足则转为就绪态进行资源分配,同时在阻塞队列中进行了排序,按照申请资源数量从小到大排序,每次只需要检测第一个即可

小结与心得体会

此次实验总体并不难,利用C++ vector可以实现动态申请资源,其中需要考虑到动态后还需要释放内存,同时,在每次进程申请时都要判断其是否满足释放资源条件,满足则释放,释放后需要检测阻塞队列,将队列中每个满足的进程都转为就绪态,其中阻塞队列中使用了一个简单的排序算法,方便进行进程调度。

源码如下:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include<vector>
#include<algorithm>

using namespace std;

struct resource
{
    int number;//进程编号
    int a;
    int b;
    int c;
};

int RESOURCE[3];//存储资源总数
int request[3];//存储各进程每次申请资源数
int num;//进程编号
bool flag=false;//判断是否需要检测阻塞队列
int nowClaim;//查找当前进程最大申请量所对应claim中的下标
vector<int> vec;//判断是老进程还是新进程
vector<resource> claim;//存储各进程最大需求
vector<resource> max_claim;//存储各进程最大需求
vector<resource> block;//存储各进程最大需求

bool checkBlock(int num)//判断num进程是否阻塞
{
	for(int j=0;j<3;j++)
	{
		if(request[j]>RESOURCE[j])
		{
			cout << "P" << num << "进程此次请求超过最大资源数,阻塞!" << endl;
			return false;
		}
	}
	return true;
}

bool safeQueue(int nowClaim)//分配资源
{
	//允许分配资源,调整资源值
	if(flag)//表示阻塞队列中的一个进程转为就绪态进行分配资源
    {
        request[0] = block[0].a;
        request[1] = block[0].b;
        request[2] = block[0].c;
        std::vector<resource>::iterator it4 = block.begin();
        block.erase(it4);//将其从阻塞队列中删除
    }
	for(int j=0;j<3;j++) RESOURCE[j]-=request[j];
	claim[nowClaim].a-=request[0];
	claim[nowClaim].b-=request[1];
	claim[nowClaim].c-=request[2];
	if(claim[nowClaim].a==0&&claim[nowClaim].b==0&&claim[nowClaim].c==0)
    {
        cout << "进程P" << claim[nowClaim].number << "结束,释放资源" << endl;
        std::vector<int>::iterator it = vec.begin();
        std::vector<resource>::iterator it1 = claim.begin();
        std::vector<resource>::iterator it2 = max_claim.begin();
        it=vec.begin()+nowClaim;
        it1=claim.begin()+nowClaim;
        it2=max_claim.begin()+nowClaim;
        vec.erase(it);
        claim.erase(it1);//表示释放资源,该进程结束
        RESOURCE[0]+=max_claim[nowClaim].a;
        RESOURCE[1]+=max_claim[nowClaim].b;
        RESOURCE[2]+=max_claim[nowClaim].c;
        max_claim.erase(it2);
        return true;
    }
	else return false;
}

int findClaim()//查找num进程对应最大申请量下标
{
    for(int i = 0;i<claim.size();i++)
    {
        if(claim[i].number == num) return i;
    }
    return -1;
}

bool comp(const resource r1, const resource r2)//排序比较器
{
    return (r1.a+r1.b+r1.c) < (r2.a+r2.b+r2.c);
}

bool allocBlock()//检查阻塞队列是否能分配资源
{
    if(block.size()==0) return false;
    sort(block.begin(),block.end(),comp);//将阻塞队列排序
    if(block[0].a<RESOURCE[0]&&block[0].b<RESOURCE[1]&&block[0].c<RESOURCE[2])
    {
        num = block[0].number;//将num刷新,方便接下来分配资源
        return true;
    }
    return false;
}

int main()
{
    resource res;
    printf("请输入资源总数(Resource):(a,b,c)\n");
    scanf("%d%d%d",&RESOURCE[0],&RESOURCE[1],&RESOURCE[2]);
    while(true)
    {
        if(!flag)//表示不需要检测阻塞队列
        {
            printf("请输入需要申请的进程编号:\n");
            cin >> num;
            res.number = num;
            vector<int>::iterator iter=find(vec.begin(),vec.end(),num);
            if(iter==vec.end())//未找到
            {
                cout << "未查找到老进程P" << num << endl;
                vec.push_back(num);
                printf("请输入P%d进程所需资源总数(claim):\n",num);
                cin >> res.a >> res.b >> res.c;
                claim.push_back(res);
                max_claim.push_back(res);
            }
            printf("请输入进程P%d申请的资源数量:(request)(不可超过最大申请资源数claim)\n",num);
            nowClaim = findClaim();//查找当前进程最大申请量的下标
            cout <<  "nowClaim = " << nowClaim << endl;
            if(nowClaim>=0) printf("P%d进程最大申请资源数为:%d %d %d\n",num,claim[nowClaim].a,claim[nowClaim].b,claim[nowClaim].c);
            cin >> request[0] >> request[1] >> request[2];
        }
        else//表示上次分配资源后有进程结束释放资源,需要检测阻塞队列
        {
            if(!allocBlock())
            {
                flag = false;//如果阻塞队列没有符合进程则下次不用检测阻塞队列,反之下次继续
                continue;
            }
            cout << "P" << num << "进程由阻塞态转为就绪态" << endl;
        }
        if(checkBlock(num))//checkBlock检测是否会阻塞
        {
            cout << "允许P" << num << "进程分配资源" << endl;
            nowClaim = findClaim();//查找当前进程最大申请量
            if(safeQueue(nowClaim)) flag=true; //某进程结束,释放资源
            else 
            {
                if(block.size()==0) flag=false;//未释放资源且阻塞队列为空则重新输入(避免阻塞队列中取出一个后就不管剩下阻塞的进程了)
            }
            cout << "当前资源剩余量:" << RESOURCE[0] << "  " << RESOURCE[1] << "  " << RESOURCE[2] << endl;
        }
        else //阻塞
        {
            res.a = request[0];
            res.b = request[1];
            res.c = request[2];
            block.push_back(res);
        }
    }

}
  • 14
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计一个n个并发进程共享m个系统资源的程序以实现银行家算法。要求: 1) 简单的选择界面; 2) 能显示当前系统资源的占用和剩余情况。 3) 为进程分配资源,如果进程要求的资源大于系统剩余的资源,不与分配并且提示分配不成功; 4) 撤销作业,释放资源。 编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁的发生。 银行家算法分配资源的原则是:系统掌握每个进程对资源的最大需求量,当进程要求申请资源时,系统就测试该进程尚需资源的最大量,如果系统中现存的资源数大于或等于该进程尚需求资源最大量时,就满足进程的当前申请。这样就可以保证至少有一个进程可能得到全部资源而执行到结束,然后归还它所占有的全部资源供其它进程使用。 银行家算法中的数据结构 (1)可利用资源向量Available(一维数组) 是一个含有m个元素,其中的每一个元素代表一类可利用的资源数目,其初值是系统中所配置的该类全部可用资源数目。如果Available[j]=k, 表示系统中现有Rj类资源k个。 (2)最大需求矩阵Max(二维数组) m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k, 表示进程i需要Rj类资源的最大数目为k。 (3)分配矩阵Allocation(二维数组) m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation(i,j)=k, 表示进程i当前已分得Rj类资源k个。 (4)需求矩阵Need (二维数组) 是一个含有n*m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need(i,j)=k, 表示进程i还需要Rj类资源k个,方能完成其任务。 Need(i,j)= Max(i,j)-Allocation(i,j)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值