admin 管理员组

文章数量: 887021

实验六 银行家算法的模拟与实现

完整课程设计源码及其报告查看:陈陈的操作系统课程设计

1、实验目的

(1) 进一步理解进程的并发执行。

(2) 加强对进程死锁的理解,理解安全状态与不安全状态的概念。

(3) 掌握使用银行家算法避免死锁问题。

2、实验基本知识及原理

(1)基本概念

死锁:多个进程在执行过程中,因为竞争资源会造成相互等待的局面。如果没有外力作用,这些进程将永远无法向前推进。此时称系统处于死锁状态或者系统产生了死锁。

安全序列:系统按某种顺序并发进程,并使它们都能达到获得最大资源而顺序完成的序列为安全序列。

安全状态:能找到安全序列的状态称为安全状态,安全状态不会导致死锁。

不安全状态:在当前状态下不存在安全序列,则系统处于不安全状态。

(2)银行家算法

银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要满足多个客户的借贷周转,为了防止银行家资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其它进程使用资源。如果资源分配不当,就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。当一进程提出资源申请时,银行家算法执行下列步骤以决定是否向其分配资源:

1)检查该进程所需要的资源是否已超过它所宣布的最大值。

2)检查系统当前是否有足够资源满足该进程的请求。

3)系统试探着将资源分配给该进程,得到一个新状态。

4)执行安全性算法,若该新状态是安全的,则分配完成;若新状态是不安全的,则恢复原状态,阻塞该进程。

3、实验内容

本实验的内容是要通过编写和调试一个模拟系统动态分配资源的银行家算法程序,有效地避免

死锁发生。具体要求如下:

(1) 初始化时让系统拥有一定的资源;

(2) 用键盘输入的方式允许进程动态申请资源;

(3) 如果试探分配后系统处于安全状态,则修改系统的资源分配情况,正式分配资源;

(4) 如果试探分配后系统处于不安全状态,则提示不能满足请求,恢复原状态并阻塞该进程。29

4、 银行家算法中的数据结构与流程图

(1)数据结构(详见教材P171):

资源总量向量 Resourcem 维,表示 m 种资源的总量。

可用资源向量 Availablem 维,表示未分配的各种可用资源数量。

需求矩阵 Claimn*m 矩阵,表示 n 个进程对 m 类资源的最大需求。

分配矩阵 Allocationn*m 矩阵,表示 n 个进程已分配的各种资源数。

**(2)算法的程序流程图:**请补充画出算法程序流程图。

5、 银行家算法编程实现

根据银行家算法及其数据结构,利用 C/C++语言进行编程实现。

6、 实验结果与分析

7、 实验总结

实验源码如下:

#define _CRT_SECURE_NO_WARNINGS // VS用scanf()函数才需要的定义

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  M  4 //总进程数
#define  N  3 //资源种类
int ALL_RESOURCE[3] = { 8, 5, 7 };//各种资源的数目总和
int MAX[M][N] = { { 3, 1, 2 }, { 5, 1, 3 }, { 3, 1, 4 }, { 4, 2, 2 } }; //M个进程对N类资源最大资源需求量
int AVAILABLE[N]; //系统可用资源数
int ALLOCATION[4][3] = { { 1, 0, 0 }, { 5, 1, 2 }, { 2, 1, 1 }, { 0, 0, 2 } }; //M个进程已经得到N类资源的资源量
int NEED[M][N]; //M个进程还需要N类资源的资源量
int Request[N]; //请求资源个数

void showdata() //函数showdata,输出资源分配情况
{
	int i, j;
	printf("各种资源的总数量为(all):[");
	for (j = 0; j < N; j++){
		printf(" %d", ALL_RESOURCE[j]);
	}
	printf(" ]\n\n");
	
	printf("系统目前各种资源可用的数为(available):[");
	
	for (j = 0; j < N; j++){
		printf(" %d", AVAILABLE[j]);
	}
	printf(" ]\n\n");

	printf("     进程已得资源表(Allocation) \n");
	printf("------------------------------------\n");
	printf("|  P/S  |  资源0 |  资源1 |  资源2 |\n");
	printf("------------------------------------\n");
	for (i = 0; i<M; i++)
	{
		printf("|进程p%d:|    ", i);
		for (j = 0; j < N; j++){
			printf("%d   |    ", ALLOCATION[i][j]);
		}
	printf("\n");
	printf("------------------------------------\n");
		
	}
	printf("\n");
	printf("        进程所需资源表(Need)\n");
	printf("------------------------------------\n");
	printf("|  P/S  |  资源0 |  资源1 |  资源2 |\n");
	printf("------------------------------------\n");
	for (i = 0; i < M; i++){
		for (i = 0; i<M; i++)
		{
			printf("|进程p%d:|    ", i);
			for (j = 0; j < N; j++){
				printf("%d   |    ", NEED[i][j]);
			}
			printf("\n");
			printf("------------------------------------\n");
		}
	}
	
	printf("\n");
}

void changdata(int k) //分配资源
{
	int j;
	for (j = 0; j<N; j++)
	{
		AVAILABLE[j] = AVAILABLE[j] - Request[j];
		ALLOCATION[k][j] = ALLOCATION[k][j] + Request[j];
		NEED[k][j] = NEED[k][j] - Request[j];
	}
}

void rstordata(int k) //恢复现场
{
	int j;
	for (j = 0; j < N; j++)
	{
		AVAILABLE[j] = AVAILABLE[j] + Request[j];
		ALLOCATION[k][j] = ALLOCATION[k][j] - Request[j];
		NEED[k][j] = NEED[k][j] + Request[j];
	}
}


int chkerr(int s) //函数chkerr,检查是否安全
{
	int i = s;
	int flag = 0;
	int *FINISH = (int *)malloc(sizeof(int) * M);
	int *WORK = (int *)malloc(sizeof(int)* N);
	int *array = (int *)malloc(sizeof(int)* M);
	int cnt = 0;
	int j;

	memset(FINISH, 0, sizeof(FINISH));
	memset(WORK, 0, sizeof(WORK));
	printf("系统当前可用资源:");
	for (j = 0; j < N; j++)
	{
		WORK[j] = AVAILABLE[j]; // 各分配的资源回收
		printf("%d ", WORK[j]);
	}
	printf("\n");
	{
		int j;
		for (j = 0; j < N; j++){ // 资源检查
			if (NEED[i][j] > AVAILABLE[j]){ // 进程i所需要的资源j能否被满足
				flag = 1; // 有不满足的,就退出
				break;
			}
		}
	}
	
	if (flag == 0){
		int j;
		FINISH[i] = 1; //i号进程,可以执行
		printf("进程p%d执行\n", i);
		printf("系统当前可用资源:");
		for (j = 0; j < N; j++)
		{
			WORK[j] += ALLOCATION[i][j]; // 各分配的资源回收
			printf("%d ", WORK[j]);
		}
		printf("\n");
		array[cnt++] = i;
	}

	while (1){
		int i;
		int flag1 = 0;
		
		for (i = 0; i < M; ){
			int sum = 0;
			int k;
			for (k = 0; k < M; k++){
				sum += FINISH[k];
			}
			if (sum == M){
				int ij;
				printf("存在安全序列:[ ");
				for (ij = 0; ij < M; ij++){
					printf("p%d ", array[ij]);
				}
				printf(" ]");
				printf("\n");
				printf("【经安全性检查,系统安全,本次分配成功。】\n");
				printf("\n");
				return 1;
			}
	
			if (FINISH[i] != 1){
				flag1 = 0;
				for (int j = 0; j < N; j++){ // 资源检查
					if (NEED[i][j] > WORK[j]){ // 进程i所需要的资源j能否被满足
						flag1 = 1; // 有不满足的,就退出
						break;
					}
				}
			}

			if (flag1 == 0 && FINISH[i] != 1 ){ // 表示i进程没执行,且可以执行
				int j;
				FINISH[i] = 1; //i号进程,可以执行
				printf("进程p%d执行\n", i);
				printf("系统当前可用资源:");
				for (j = 0; j < N; j++)
				{
					WORK[j] +=  ALLOCATION[i][j]; // 各分配的资源回收
					printf("%d ", WORK[j]);
				}
				printf("\n");
				array[cnt++] = i;
				i = 0;
			}
			else{ // 不能执行判断下一个进程
				i++;
			}
		}
		printf("\n");
		printf("【系统不安全!!! 本次资源申请不成功!!!】\n");
		printf("\n");
		return 0;

	}
}

主函数调用模块:

实验结果截图及分析:

更多课程设计源码请进主页查看搜索:陈陈不会敲代码

完整课程设计报告请下载:陈陈的操作系统课程设计源码及其报告

完整报告包含以下内容的源码以及实验报告:

资源展示如下:


本文标签: 银行家 算法 课程设计 操作系统