操作系统实验二

操作系统实验连接

实验一 进程调度算法
实验二 预防死锁-银行家算法
实验三 分区分配算法+请求式分页存储管理算法
实验四 文件系统


银行家算法

之前在网上找了一些这次实验的代码,发现有的代码写的实在是看不懂,循环判断语句不知道是什么牛鬼蛇神,这告诉我们代码可读性多么的重要啊!
后来又参考了一些不错的代码,以下是n个进程m类资源原作者链接:https://blog.youkuaiyun.com/wl1780852311/article/details/103085551

实验目的

1.
本次实验要求设计一个几个并发进程共享m个系统资源的系统,并采用银行家算法防止死锁的发生。进程可动态的申请资源和释放资源,系统按各进程的申请动态地分配资源。在系统运行时能显示各进程申请和释放资源、动态分配资源的过程。
2.
本次实验中有3个并发进程共享10个系统资源。在3个进程申请系统资源之和不超过10时,不可能发生死锁,因为各个进程资源都能满足。在有一个进程申请的系统资源数超过10时,必然会发生死锁。应该排队这两种情况。程序采用人工输入各进程的申请资源序列。如果随机给各进程分配资源,就可能发生死锁,这也就是不采用防止死锁算法的情况。

算法步骤

1、银行家算法中的数据结构

(1) 可利用资源向量Available。这是一个int类型的变量,代表现在可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果Available=K,则表示系统中现有可用资源K个。

(2) 最大需求数组Max。这是一个含有n个元素的数组,它定义了系统中n个进程中的每一个进程对资源的最大需求。如果Max[i]=K,则表示进程i需要资源的最大数目为K。

(3) 分配数组Allocation。这也是一个含有n个元素的数组,它定义了系统中当前已分配给每一进程的资源数。如果Allocation[i]=K,则表示进程i当前已分得资源的数目为K。

(4) 需求矩阵Need。这也是一个含有n个元素的数组,用以表示每一个进程尚需的各类资源数。如果Need[i]=K,则表示进程i还需要K个资源,方能完成其任务。
Need[i]=Max[i]-Allocation[i]

2、银行家算法

设Request[i]是进程Pi的请求资源,如果Request[i]=K,表示进程Pi需要K个资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1) 如果Request[i]≤Need[i],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。

(2) 如果Request[i]≤Available[i],便转向步骤(3);否则, 表示尚无足够资源,Pi须等待。

(3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[i]= Available[i]- Request[i];
Allocation[i]= Allocation[i]+ Request[i];
Need[i]= Need[i]- Request[i];

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

3、安全性算法

(1) 设置两个变量:
① 工作变量Work: 它表示系统可提供给进程继续运行所需的资源数目,在执行安全算法开始时,Work=Available;
② Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。

(2) 从进程集合中找到一个能满足下述条件的进程:
① Finish[i]=false;
② Need[i]≤Work; 若找到, 执行步骤(3), 否则,执行步骤(4)。

(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work =Work+Allocation[i];
Finish[i]=true;
执行步骤(2)

(4) 如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。

4、部分执行过程

在输入进程1的请求资源数量后,显示的内容(即安全序列)分别为:
Work - 现在剩余的系统资源量;
Need - 目前该进程还需要的资源数量;
Allo - 进程当前已被分配的资源数量;
W+A - 也就是Work+Allo是该进程被执行完毕释放资源后的可用资源数量,也是接下一个进程的Work;
Finish - 进程是否执行完毕,1为执行完。

这次显示的进程顺序为所有进程在检测是否安全时,在安全序列中被执行完毕的顺序。
部分终端截图

代码

#include<bits/stdc++.h>
using namespace std;

const int n=3;//进程数
//数据结构
int available= 5; //可利用资源
int Max[n]= {7,3,9}; //最大需求
int allocation[n]= {0,2,3}; //分配资源
int need[n];//需求数组
//Need[i]=Max[i]-Allocation[i]
int Request[n];//请求
int Work;//工作资源
bool Finish[n];//系统是否有足够的资源分配
int WaddA[n];//记录W+A
int p[n];//记录进程号
int work[n];//记录work

void menu()
{
	cout<<endl;
	cout<<"1. 初始化"<<endl;
	cout<<"2. 查看当前资源分配表"<<endl;
	cout<<"3. 请求资源"<<endl;
	cout<<"4. 退出"<<endl;
	cout<<"请选择:"<<endl;
}

void init()
{
	for(int i=0; i<n; i++)
	{
		cout<<"输入进程P"<<i<<"的资源分配情况:\n";
		cout<<"Max:";
        cin>>Max[i];
		cout<<"\nAllocation:";
        cin>>allocation[i];
	}
	cout<<"输入当前可用资源数量";
	cout<<"Avaliable:";
    cin>>available;
}

void print()
{
	//计算Need
	for(int i=0; i<n; i++)
	{
		need[i]=Max[i]-allocation[i];
	}
	//打印
	cout<<"\tMax   "<<"\tAllo  "<<"\tNeed  "<<"\tAvalia"<<endl;
	for(int i=0; i<n; i++)
	{
		cout<<"P"<<i<<"    \t";
		cout<<Max[i];
		cout<<"\t";
		cout<<allocation[i];
		cout<<"\t";
		cout<<need[i];
		cout<<"\t";
		if(i==0)
		{
			cout<<available;
			cout<<endl;
		}
		else
			cout<<endl;
	}
}

//打印安全序列
void print_sequence()
{
	cout<<"\tWork   "<<"Need  "<<"\tAllo  "<<"\tW+A "<<"    Finish"<<endl;
	for(int i=0; i<n; i++)
	{
		cout<<"P"<<p[i]<<"    \t";
		cout<<work[p[i]];
		cout<<"\t";
		cout<<need[p[i]];
		cout<<"\t";
		cout<<allocation[p[i]];
		cout<<"\t";
		cout<<WaddA[p[i]];
		cout<<"\t";
		cout<<Finish[p[i]]<<endl;
	}
}

bool safety()
{
	//初始化
	int w=0;
	Work=available;
	for(int i=0; i<n; i++)
		Finish[i]=false;
	int count=0;
	while(1)
	{
	    //i是进程号
		for(int i=0; i<n; i++)
		{
			if(Finish[i]==false)
			{
				if(need[i]<=Work)
				{
					work[i]=Work;
                    Work=Work+allocation[i];
                    WaddA[i]=Work;
					Finish[i]=true;
					p[w++]=i;//记录进程完成的顺序
					count=0;
				}
			}
		}
		count++;
		if(count>=n)
			break;
	}
	int flag=1;
	for(int i=0; i<n; i++)
	{
		if(Finish[i]==false)
		{
			flag=0;
		}
	}
	if(flag==1)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void Banker()
{
	cout<<"输入请求资源的进程号:\n";
	int pid;
	cin>>pid;
	cout<<"输入请求资源的数量:";
	cin>>Request[pid];
	if(Request[pid]>need[pid])
    {
        cout<<"请求资源数量大于Need数量,分配失败!"<<endl;
        return ;
    }
    else
    {
        if(Request[pid]>available)
        {
            cout<<"请求资源数量大于Aailable数量,需等待!"<<endl;
            return;
        }
    }

	available=available-Request[pid];
    allocation[pid]=allocation[pid]+Request[pid];
    need[pid]=need[pid]-Request[pid];

	bool safe = safety();
	if(safe==true)
	{
		//打印
		print_sequence();
		cout<<"请求成功!!"<<endl;
	}
	else
	{
		cout<<"系统将进入不安全状态,请求失败!!"<<endl;
		available=available+Request[pid];
        allocation[pid]=allocation[pid]-Request[pid];
        need[pid]=need[pid]+Request[pid];
	}
}

int main()
{
	int flag=1;
	while(1)
	{
		int sel;
		menu();
		cin>>sel;
		switch(sel)
		{
			case 1:
				init();
				break;
			case 2:
				print();
				break;
			case 3:
				Banker();
				break;
			case 4:
				flag=0;
				break;
		}
		if(flag==0)
			break;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值