【实验报告】操作系统,银行家算法,

目录

 

一、实验目的

二.实验内容

三、算法流程图

四.源程序及注释

五.运行结果:

六.实验小结:


一、实验目的

1.银行家算法是一种最有代表性的避免死锁的算法。

2.在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性;

3.若分配不会导致系统进入不安全状态,则分配,否则等待。

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

 

二.实验内容

银行家算法中的数据结构 

1)可利用资源向量Available

是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。 

2)最大需求矩阵Max

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

3)分配矩阵Allocation

这也是一个n×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] 

银行家算法

设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

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

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

(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:

Available[j]=Available[j]-Requesti[j];

Allocation[i,j]=Allocation[i,j]+Requesti[j];  

Need[i,j]=Need[i,j]-Requesti[j];

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

安全性算法

1)设置两个向量:

工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available;

工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。 

2)从进程集合中找到一个能满足下述条件的进程:         

Finish[i]=false;

Need[i,j]≤Work[j];若找到,执行 (3),否则,执行 (4)

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

Work[j]=Work[i]+Allocation[i,j];

Finish[i]=true;

go to step 2;

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

三、算法流程图

四.源程序及注释

 

程序中使用的数据结构及符号说明。
1.全局变量定义
int Available[100]; //可利用资源向量Available ,是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j] = K,则表示系统中现有Rj类资源K个。
int Max[50][100];   //最大需求矩阵Max 这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i, j] = K,则表示进程i需要Rj类资源的最大数目为K。
int Allocation[50][100];  //已经分配矩阵
int Need[50][100];        //进程需求矩阵
int Request[50][100];     //M个进程还需要N类资源的资源量
int Finish[50];//
int p[50];
int m, n;   //M个进程,N类资源
2.程序包含函数:

//安全性算法
int Safe();

 

打印一份源程序,必须要有注释。
 


#include <iostream>
using namespace std;
//全局变量定义
int Available[100]; //可利用资源向量Available ,是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j] = K,则表示系统中现有Rj类资源K个。
int Max[50][100];   //最大需求矩阵Max   这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i, j] = K,则表示进程i需要Rj类资源的最大数目为K。
int Allocation[50][100];  //已经分配矩阵
int Need[50][100];        //进程需求矩阵
int Request[50][100];     //M个进程还需要N类资源的资源量
int Finish[50];//
int p[50];
int m, n;   //M个进程,N类资源

//安全性算法
int Safe()
{
	int i, j, l = 0;
	int Work[100]; //可提供给进程各类资源资源数组
	for (i = 0; i < n; i++)
		Work[i] = Available[i];//在执行安全算法开始时,可提供的各类资源数目=系统现有各类资源数目;Work=Available; 
	for (i = 0; i < m; i++)
		Finish[i] = 0;//表示系统是否有足够的资源分配给进程
	for (i = 0; i < m; i++)
	{
		if (Finish[i] == 1)//工作向量等于1,进程执行
			continue;
		else
		{
			for (j = 0; j < n; j++)
			{
				if (Need[i][j] > Work[j])
					break;
			}
			if (j == n)
			{
				Finish[i] = 1;
				for (int k = 0; k < n; k++)
					Work[k] = Work[k] + Allocation[i][k];//直至完成,并释放出分配给它的资源,故应执行可提供资源数量更新
				p[l++] = i;
				i = -1;
			}
			else continue;
		}
		if (l == m)
		{
			cout << "系统是安全的" << '\n';
			cout << "系统安全序列是:\n";
			for (i = 0; i < l; i++)
			{
				cout << p[i];
				if (i != l - 1)
					cout << "-->";
			}
			cout << '\n';
			return 1;
		}
	}
	return 0;
}

//银行家算法
int main()
{
	int i, j, mi;
	cout << "输入进程的数目:\n";
	cin >> m;
	cout << "输入资源的种类:\n";
	cin >> n;
	cout << "输入每个进程最多所需的各类资源数,按照" << m << "x" << n << "矩阵输入\n";
	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
			cin >> Max[i][j];//将用户输入的资源需求放进最大需求矩阵数组里

	cout << "输入每个进程已经分配的各类资源数,按照" << m << "x" << 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];
	Safe();
	while (1)
	{
		cout << "输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
		cin >> mi;
		cout << "输入进程所请求的各个资源的数量\n";
		for (i = 0; i < n; i++)
			cin >> Request[mi][i];
		for (i = 0; i < n; i++)
		{

			if (Request[mi][i] > Need[mi][i])
			{
				cout << "所请求资源数超过进程的需求量!\n";
				return 0;
			}
			if (Request[mi][i] > Available[i])
			{
				cout << "所请求资源数超过系统所有的资源数!\n";
				return 0;
			}
		}
		for (i = 0; i < n; i++)
		{
			Available[i] = Available[i] - Request[mi][i];//可利用资源=可利用资源-进程需要

			Allocation[mi][i] = Allocation[mi][i] + Request[mi][i];//已分配资源=已分配资源+进程需要

			Need[mi][i] = Need[mi][i] - Request[mi][i];//进程还需资源=进程还需资源-进程需要
		}
		if (Safe())
			cout << "同意分配请求\n";
		else
		{
			cout << "对不起.你的请求被拒绝…\n";
			for (i = 0; i < n; i++)
			{
				Available[i] = Available[i] - Request[mi][i];//可利用资源=可利用资源-进程需要

				Allocation[mi][i] = Allocation[mi][i] + Request[mi][i];//已分配资源=已分配资源+进程需要

				Need[mi][i] = Need[mi][i] - Request[mi][i];//进程还需资源=进程还需资源-进程需要
			}
		}
		for (i = 0; i < m; i++)
			Finish[i] = 0;
		
	}

	return 0;
}

五.运行结果:

六.实验小结:

1.银行家算法是一种用来避免操作系统死锁出现的有效算法。

2.死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

3.死锁的发生必须具备以下四个必要条件:

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不抢占条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)循环等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

4.避免死锁算法中最有代表性的算法就是Dijkstra E.W 于1968年提出的银行家算法,银行家算法是避免死锁的一种重要方法,防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。

5.为实现银行家算法,系统必须设置若干数据结构,同时要解释银行家算法,必须先解释操作系统安全状态和不安全状态。

6.安全序列:是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。7.安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。

8.安全状态一定是没有死锁发生。不安全状态:不存在一个安全序列。不安全状态不一定导致死锁。

  • 89
    点赞
  • 610
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值