操作系统-进程死锁:银行家算法

进程死锁:银行家算法

问题描述

​ 设计程序模拟避免进程死锁的银行家算法的工作过程。假设有系统中有n个进程P1, … ,Pn,有m类可分配的资源R1, … ,Rm,在T0时刻,进程Pi分配到的j类资源为Allocationij个,它还需要j类资源Needij个,系统目前剩余j类资源Workj个,现采用银行家算法进行资源分配避免死锁的发生。

1)判断当前状态T0是否安全,如果安全,给出安全序列;如果不安全给出理由。

2)对于下一个时刻T1,某个进程Pk会提出请求Request(R1, … ,Rm),判断是否可以分配给Pk进程请求的资源。

3)输入以下信息,或者将这些信息存入文件,并读入该文件。

  • 进程个数n,资源种类m,以及各类资源的实例个数,例如:

The number of processes: 5

The number of resource types: 3

The numbers of the resources for each resource type : 10, 5, 7

  • T0时刻各个进程的资源分配情况、最大资源需求、剩余所需资源、以及剩余的资源情况,例如:

image-20220506154508999

  • T1时刻,发出请求的进程编号,以及请求的资源情况,例如:

Who makes a further request (the number of the process): 1

The request : 1, 0, 2

4)输出:

  • 判断T0时刻是否安全的详细信息,如果安全,则输出安全的进程序列,否则提示不安全信息。例如:

image-20220506154859918

security sequence : P1,P3,P4,P2,P0

  • 判断T1时刻满足进程请求后系统是否安全的详细信息,最后给出是否可以满足该进程请求的结论信息。例如:

image-20220506155107234

Conclusion : Requests of p1 is able to be granted.

实验环境

  • Windows 11
  • Visual Studio Code
  • GCC version 8.1.0

输入

  • 输入所需的信息和系统的当前状态。
  • 输出状态的判断,如果状态是安全的,则输出进程的安全顺序。
  • 在T1时间内输入请求。

输出

  • 显示T0时间内系统的状态。
  • 调用安全算法以查看当前状态是否安全,并显示详细结果。
  • 输出状态判断和请求能否被批准的结论。如果状态是安全的,则输出进程的安全序列。如果不安全或者无新请求则退出。

测试数据

  • 进程和资源的数据如问题描述所示
  • 发起请求的进程:P1
  • 请求的资源数量:1 0 2
  • 测试系统不安全和请求资源超出剩余资源的情况

实验设计

数据结构

//剩余的可使用资源
int available[ResourceNum] = {3, 3, 2};
//进程的最大需求
int MAX[ProcessNum][ResourceNum] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};
//进程以及占有的资源
int allocation[ProcessNum][ResourceNum] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};
//进程还需要的资源
int need[ProcessNum][ResourceNum] = {{7, 4, 3}, {1, 2, 2}, {6, 0, 0}, {0, 1, 1}, {4, 3, 1}};
//判断是否安全
bool Finish[ProcessNum];
//安全序列号
int safeSeries[ProcessNum] = {0};
//进程请求资源数
int request[ResourceNum];

主要函数功能和参数

void print()

  • 功能:打印系统信息
  • 参数:无

void safePrint(int work[ResourceNum], int i)

  • 功能:打印安全检查信息
  • 参数:工作向量、进程的索引

void safePrint(int work[ResourceNum], int i)

  • 功能:打印安全检查信息
  • 参数:工作向量、进程的索引

bool is_safe()

  • 功能:安全性检查
  • 参数:无

系统框架图

img

流程图

在这里插入图片描述

实验结果与分析

结果展示与描述

  • 初始信息

image-20220506183240454

  • 进程1请求资源1 0 2

image-20220506183256745

  • 不安全和请求资源超出剩余资源的情况

image-20220506183753995

结果分析

  • 剩余资源满足P1需求,首先分配给P1
  • P1完成后,释放资源,此时剩余资源满足P3需求
  • 以此类推,每次有进程完成释放资源后,都存在满足条件的进程
  • 以此得到安全序列并打印
  • P1申请资源后,对调整后的资源再进行安全性检查
  • 能够得到安全序列
  • 若P4再申请资源0 3 0,则无法得到安全序列
  • 若申请的资源超出剩余资源,则报错并退出程序

总结

  • 银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
  • 在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
  • 理解了进程死锁相关概念,包括资源的请求、资源持有、安全状态等等。掌握了判断进程是否处于安全状态的过程。掌握了死锁避免方法中的银行家算法。

源代码

#include <iostream>
using namespace std;
#define ProcessNum 5  //进程总数
#define ResourceNum 3 //资源种类
#define TRUE 1
#define FALSE 0
//剩余的可使用资源
int available[ResourceNum] = {3, 3, 2};
//进程的最大需求
int MAX[ProcessNum][ResourceNum] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};
//进程以及占有的资源
int allocation[ProcessNum][ResourceNum] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};
//进程还需要的资源
int need[ProcessNum][ResourceNum] = {{7, 4, 3}, {1, 2, 2}, {6, 0, 0}, {0, 1, 1}, {4, 3, 1}};
//判断是否安全
bool Finish[ProcessNum];
//安全序列号
int safeSeries[ProcessNum] = {0};
//进程请求资源数
int request[ResourceNum];

//打印系统信息
void print()
{
	cout << "-------------------------------------------- " << endl;
	cout << "当前系统各类资源剩余:";
	for (int i = 0; i < ResourceNum; i++)
	{
		cout << available[i] << " ";
	}
	cout << endl;
	cout << "当前系统资源情况:" << endl;
	cout << "PID" << '\t' << "MAX" << '\t' << "Allocation" << '\t' << "Need" << endl;
	for (int i = 0; i < ProcessNum; i++)
	{
		cout << i << '\t';
		for (int j = 0; j < ResourceNum; j++)
		{
			cout << MAX[i][j] << " ";
		}
		cout << '\t';
		for (int j = 0; j < ResourceNum; j++)
		{
			cout << allocation[i][j] << " ";
		}
		cout << '\t' << '\t';
		for (int j = 0; j < ResourceNum; j++)
		{
			cout << need[i][j] << " ";
		}
		cout << endl;
	}
	cout << "---------------------------------------------------------" << endl;
	// cout << endl;
}

//打印安全检查信息
void safePrint(int work[ResourceNum], int i)
{
	cout << "PID" << '\t' << "Work" << '\t' << "Need" << '\t' << "Allocation" << '\t' << "Work+Allocation" << endl;
	cout << i << '\t';
	for (int j = 0; j < ResourceNum; j++)
	{
		cout << work[j] << " ";
	}
	cout << '\t';
	for (int j = 0; j < ResourceNum; j++)
	{
		cout << need[i][j] << " ";
	}
	cout << '\t';
	for (int j = 0; j < ResourceNum; j++)
	{
		cout << allocation[i][j] << " ";
	}
	cout << '\t' << '\t';
	for (int j = 0; j < ResourceNum; j++)
	{
		cout << allocation[i][j] + work[j] << " ";
	}
	cout << endl;
}

//安全性检查
bool is_safe()
{
	int allFinish = 0;					  //完成的进程数
	int safeIndex = 0;					  //安全序列下标
	int work[ResourceNum];				  //工作向量
	for (int i = 0; i < ResourceNum; i++) //初始work=available
	{
		work[i] = available[i];
	}
	for (int i = 0; i < ProcessNum; i++) //初始Finish全为FALSE,有足够资源分配给进程时为TRUE
	{
		Finish[i] = FALSE;
	}
	int i = 0, j = 0, k = 0;
	// int temp = 0;
	int failness = 0;				//自上一个满足的进程起,接下来的进程不满足的次数
	while (allFinish != ProcessNum) //当进程还没全部结束时
	{
		j = 0;
		if (Finish[i] != true)
		{
			for (j = 0; j < ResourceNum; j++)
			{
				if (need[i][j] > work[j])
				{
					failness++; //不满足次数加1
					break;
				}
			}
		}
		if (j == ResourceNum)
		{
			Finish[i] = true;
			safePrint(work, i);
			for (k = 0; k < ResourceNum; k++)
			{
				work[k] += allocation[i][k];
			}
			safeSeries[allFinish++] = i;
			failness = 0; //当前进程满足,归0
		}
		i++;
		// if (i >= ProcessNum)
		i = i % ProcessNum;
		// if (temp == allFinish)
		if (failness == ProcessNum - allFinish) //剩余进程都不满足,系统不安全,退出
			break;
		// temp = allFinish;
	}

	if (allFinish == ProcessNum)
	{
		cout << "系统安全!安全序列号为:";
		for (i = 0; i < ProcessNum; i++)
		{
			cout << safeSeries[i] << " ";
		}
		cout << endl;
		return true;
	}
	cout << "系统不安全!";
	return false;
}

int main()
{
	int curProcess = 0;
	print(); //打印资源情况
	// cout << "---------------------------------------------------------" << endl;
	cout << "系统安全性分析:" << endl;
	is_safe();
	cout << "---------------------------------------------------------" << endl;
	while (TRUE)
	{
		cout << "输入要分配的PID : ";
		cin >> curProcess;
		cout << "输入要分配给进程的资源 : ";
		for (int i = 0; i < ResourceNum; i++)
		{
			cin >> request[i];
		}
		int j;
		for (j = 0; j < ResourceNum; j++)
		{
			if (request[j] > need[curProcess][j])
			{
				cout << "所需资源超过最大值, ERROR ! " << endl;
				cout << "---------------------------------------------------------" << endl;
				return 0;
			}
		}
		for (j = 0; j < ResourceNum; j++)
		{
			if (request[j] <= available[j])
				continue;
			else
			{
				cout << "资源不足,等待中 ! " << endl;
				break;
			}
		}
		if (j == ResourceNum)
		{
			for (j = 0; j < ResourceNum; j++)
			{
				available[j] -= request[j];
				allocation[curProcess][j] += request[j];
				need[curProcess][j] -= request[j];
			}
			cout << "系统安全情况分析 : " << endl;
			if (is_safe())
			{
				cout << "分配成功 ! " << endl;
				print(); //打印信息
			}
			else //分配失败,恢复原来的状态
			{
				available[j] += request[j];
				allocation[curProcess][j] -= request[j];
				need[curProcess][j] += request[j];
				cout << "分配失败 ! " << endl;
				cout << "进程" << curProcess << "等待 ! " << endl;
			}
		}
	}
	system("pause");
	return 0;
}

  • 3
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值