死锁的避免——银行家算法(C++实现)

【实验目的】

为了了解系统的资源分配情况,假定系统的任何一种资源在任意时刻只能被一个进程使用,任何进程已经占用的资源只能由进程自己释放,而不能由其他进程抢占,当进程申请的资源不能满足时,必须等待。因此只要资源分配算法能保证进程的资源请求,且不出现循环等待,则系统不会出现死锁。
要求编写系统进行资源调度的程序。一个是随机动态地进行资源分配的模拟程序,即只要系统当前剩余资源满足进程的当前要求,就立即将资源分配给进程,以观察思索产生情况;一个是采用银行家算法,有效地避免死锁的产生。

【实验原理】

  1. 银行家算法
    银行家算法是从当前状态出发,按照系统各类资源剩余量逐个检查各进程需要申请的资源量,找到一个各类资源申请量均小于等于系统剩余资源量的进程P1。然后分配给该P1进程所请求的资源,假定P1完成工作后归还其占有的所有资源,更新系统剩余资源状态并且移除进程列表中的P1,进而检查下一个能完成工作的进程。如果所有进程都能完成工作,则找到一个安全序列,当前状态是安全的。则当前状态不安全。
  2. 安全性算法
    (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. 要求
    (1) 设计3-4个并发进程,共享系统的10个同类不可抢占的资源。各进程动态进行资源的申请和释放。
    (2) 用银行家算法和随机算法分别设计一个资源分配程序,运行整两个程序,观察系统运行情况,并对系统运行的每一步情况进行显示。
  2. 实验代码
//用银行家算法和随机算法实现资源分配
#include <iostream>
#include<string>
using namespace std;
#define MAXNUM 10
#define WAITING 0	// 表示进程正在等待
#define FINISHED 1	// 表示进程已完成
#define NONE -1		// 表示当前请求资源的进程数为0
int Available = 10;	// 10个同类不可抢占的资源

class pcb   // 进程控制块
{
public:
	pcb();			// 构造函数
	friend void AllocationTalbe(pcb Queue[], int length);// 打印资源分配表
	friend void Bankers(pcb Queue[], int length);		 // 银行家算法
	friend void ShowSeries(pcb Queue[], int length);	 // 打印安全序列
	friend void Security(pcb Queue[], int length);		 // 安全性算法
private:
	string name;   // 进程名
	int status;    // 状态
	int max;       // 资源需求总量
	int allocation;// 已占资源量
	int need;      // 仍需资源量
	bool finish;   // 能执行完标志
};

pcb::pcb()  // 构造函数,初始化进程控制块
{
	cout << "Process name:        ";
	cin >> name;            // 输入进程名
	cout << "Process MAX Require: ";
	cin >> max;             // 输入资源需求总量
	cout << "Process allocation:  ";
	cin >> allocation;      // 输入已分配资源量
	Available -= allocation; // 可用资源量减少
	need = max - allocation;// 仍需要的资源量
	cout << "Process still need:  " << need;
	cout << endl << endl;
	status = WAITING;       // 进程初始化为等待 状态
	finish = false;         // 初始化为未执行状态
}

void AllocationTalbe(pcb Queue[], int length)
{
	cout << "Resource allocation table:" << endl << endl;   // 打印资源分配情况
    cout << "┏ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓" << endl;
	cout << "┃              Max       Allocation    Need      Available┃" << endl;
	for (int i = 0; i < length; i++) {
		cout << "┃ " << Queue[i].name << "           " << Queue[i].max << "            "
			<< Queue[i].allocation << "            " << Queue[i].need << "            ";
		if (i == 0) {
			cout << Available;
		}
		cout<< "\t  ┃" << endl;
	}
    cout << "┗ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛" << endl;
}

void Security(pcb Queue[], int length);	// 安全性算法
void Bankers(pcb Queue[], int length) // 银行家算法
{
	// 提示输入请求资源的进程号,没有则输入4
	cout << endl;
	cout << "Which process has a request?" << endl;
	cout << "Enter the number of process(0-3), if none then enter '-1'" << endl;
	cout << ">> ";
	int num;
	cin >> num;
	if (num == NONE) { // 没有进程提出新的请求时,资源分配情况不变
		cout << "The resource allocation table has no change!" << endl;
	}
	else {
		cout << Queue[num].name << " requests: ";
		int request;
		cin >> request; // 输入当前请求量
		if (request > Queue[num].need) {    // 检查是否超过需求量
			cout << "The process's request can't bigger than process's need!" << endl;
			system("pause");
			exit(-1);
		}
		else {
			if (request > Available) { // 检查是否有足够的资源
				cout << "The available resource is not enough!";
				system("pause");
				exit(-1);
			}
			else {                  // 尝试将资源分配给进程
				Available -= request;
				Queue[num].allocation += request;
				Queue[num].need -= request;
				AllocationTalbe(Queue, length);// 打印新的资源分配表
			}
		}
	}
	Security(Queue, length);	//用安全性算法检验
}

int Work[MAXNUM] = { 0 };// 工作向量
int Snum[MAXNUM] = { 0 };// 安全序列中的进程序号

void ShowSeries(pcb Queue[], int length) // 打印安全序列
{
	cout << endl;
	cout << "┏ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓" << endl;
	cout << "┃              Work    Need    Allocation  Work+Allocation    Finish┃" << endl;
	for (int i = 0; i < length; i++) {
		if (Queue[Snum[i]].finish) {
			cout << "┃ " << Queue[Snum[i]].name << "            " << Work[i] << "      "
				<< Queue[Snum[i]].need << "          " << Queue[Snum[i]].allocation << "         "
				<< Work[i + 1] << "\t\t\t" << "T   ┃" << endl;
		}
	}
	cout << "┗ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛" << endl;
	cout << endl << endl;
}


void Security(pcb Queue[], int length)	// 安全性算法
{
	int i = 0, j = 0, k = 0;
	Work[i] = Available;	// Work向量初值为Available的值
	for (j = 0; j < length; j++) {
		for (k = 0; k < length; k++) {
			if ((Queue[k].finish == false) && (Queue[k].need <= Work[i]))
			{
				Work[i + 1] = Work[i] + Queue[k].allocation;
				Queue[k].finish = true;
				Snum[i++] = k;	// 记录安全队列中进程编号
			}
		}
	}
	int finish=1;
	for (j = 0; j < length; j++) {
		if (Queue[j].finish == false) {	// 无法形成安全队列
			finish = 0;
			cout << endl;
			cout << "Can't get a security series, this moment is not safe!" << endl;
			ShowSeries(Queue, length);	// 打印安全队列
			system("pause");
			exit(-1);
		}
	}
	if (finish == 1) {
		cout << endl;
		cout << "Security series: ";
		for (int i = 0; i < length; i++) {
			cout << Queue[Snum[i]].name << " ";
		}
	}
	ShowSeries(Queue, length);	// 打印安全队列
}

int main()
{
	pcb *que = new pcb[4];	// 定义四个进程
	AllocationTalbe(que, 4);// 显示储时资源分配情况
	system("cls");
	Bankers(que, 4);		// 银行家算法进行调度
	return 0;
}

【运行结果】

  1. 先创建四个进程p0, p1, p2, p3
    在这里插入图片描述
  2. 根据提示做出选择,有进程提出request则输入进程编号,没有则输入-1,一下几组测试所用数据相同,不重复截图。
    在这里插入图片描述
  3. 没有进程提出request时,经过检验可形成安全序列p1 p3 p0 p2,所以初始状态是安全的。
    在这里插入图片描述
  4. 当p3提出request为1时,尝试将资源分配给它,此时能形成安全序列p1 p3 p0 p2,所以分配给p3是安全的。
    在这里插入图片描述
  5. 当p0提出request为1时,尝试将资源分配给它,若进行分配则只能满足p1进程,无法形成安全序列。故不能分配。
    在这里插入图片描述
  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
银行家算法是一种经典的避免死锁算法,它可以确保系统在分配资源时不会进入死锁状态。该算法主要分为两个过程:安全性检查和资源分配。 安全性检查: 在系统运行时,银行家算法需要进行安全性检查,以确定当前状态是否安全。安全状态指的是系统可以满足所有进程的资源需求,而不会陷入死锁状态。 实现算法需要维护以下数据结构: - Available:表示系统中可用的资源数目。 - Allocation:表示已经分配给各个进程的资源数目。 - Need:表示每个进程还需要的资源数目。 具体实现过程如下: 1. 初始化工作: 首先,需要计算出每个进程的所需资源数目,即 Need 数组。这可以通过计算 Max - Allocation 来得到,其中 Max 表示进程所需的最大资源数目。 2. 安全性检查: 银行家算法的安全性检查基于两个概念:安全序列和安全状态。 安全序列:指的是一系列进程的执行顺序,这些进程都能够完成任务,不会进入死锁状态。 安全状态:指的是系统可以分配资源,使得所有进程都能够完成任务,不会进入死锁状态。 安全性检查的具体实现过程如下: (1)初始化工作: 设置 Work 数组为 Available 数组的值;Finish 数组的值都为 false。 (2)循环检查: 循环检查所有进程,找到一个满足以下条件的进程: - Finish[i] = false - Need[i] <= Work 如果找到了这样的进程,则将该进程的资源释放,并将它加入安全序列中。同时,更新 Work 数组的值。 如果没有找到这样的进程,则说明系统无法满足所有进程的资源需求,进入死锁状态。 3. 资源分配: 如果系统处于安全状态,则可以进行资源分配。资源分配的过程需要按照以下规则进行: - 判断是否能够满足当前进程的资源需求(即 Need[i] <= Available)。 - 如果可以满足,则将资源分配给该进程,同时更新 Available 和 Allocation 数组的值。 - 如果无法满足,则该进程必须等待资源。 需要注意的是,资源分配过程中,需要检查是否会破坏系统的安全状态。如果分配资源后,系统无法保持安全状态,则应该撤销分配操作,等待系统恢复到安全状态后再进行分配。 综上所述,银行家算法是一种非常重要的避免死锁算法。通过合理地分配系统资源,可以避免系统陷入死锁状态,提高系统的可靠性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值