编程序模拟银行家算法

写在前面

此项目为计算机操作系统课程设计,题目为编程序模拟银行家算法,是经过多方参考最终实现的简陋课设,以及相应的课程设计报告资料,可供同样需要完成相关课设的小伙伴参考使用。

链接: https://pan.baidu.com/s/1a-YKiG8peTqMhe9JopShBg?pwd=yg3k
提取码: yg3k 复制这段内容后打开百度网盘手机App,操作更方便哦

此链接为本次课设相关报告和源代码(后文也有贴出)资料,PPT是随便乱写的,做不得数,看看就行。网盘链接设置的永久有效,若失效可联系俺要链接。

温馨提示:网上找的资料,该改改就改改,如有雷同,dddd,希望各位课程设计能通过并获得理想成绩。

1.1.1 背景和意义

银行家算法是荷兰学者Dijkstra为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。后来该算法被用在操作系统中,用于避免死锁,它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。

1.1.2 任务概述

用C语言模拟银行家算法对死锁的避免。对于进程死锁的避免问题,分为两种状态:安全状态和非安全状态。在避免死锁的方法中,允许进程动态申请资源分配之前,预先计算此次资源分配的安全性。如果此次分配不会导致系统进入不安全状态,则将资源分配给进程。否则,让进程进入等待状态。
所谓安全状态是指系统能够按照某种进程顺序,来为每个进程P分配所需的资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺利地完成。如果系统无法找到这样一个序列,则系统处于不安全状态。只要系统处于安全状态,系统就可以避免进入死锁状态。

1.1.3 设计环境

(1) 硬件:PC机,要求能运行Windows XP、Windows7或Windows 10操作系统。
(2) 软件:
 操作系统:Windows系列。
 数据库系统:无
 编译软件:Visual Studio 2019
 程序设计语言:C语言

2.2 系统整体功能图

2.2.1 功能模块图

银行家算法系统中包括七个模块,分别为初始化模块,主函数模块和安全检测模块。其中初始化模块包括默认初始化功能和自定义初始化功能;主函数模块包括用户帮助和回收分配失败的资源;其他功能模块包括请求资源分配、检测是否存在安全序列以及查看系统分配结果的功能。具体如图2.1所示。
在这里插入图片描述
图2.1 银行家算法功能模块图

2.7 程序运行结果

2.7.1 运行界面截图和结果分析

使用默认初始化功能,即参考例题的初始化,输出整理出来的进程相关信息和资源信息。运行结果如图2.5所示。
在这里插入图片描述
图2.5 默认初始化功能截图
使用自定义初始化功能,同样参考例题输入系统进程数m、资源数n、各类资源总数All、各进程最大需求资源数MAX,进程已经占有的资源数Allocate,输出系统剩余资源数Available。运行结果如图2.6所示。
在这里插入图片描述
图2.6 自定义初始化功能截图
(1)t0时刻是否为安全状态。
根据默认的初始化进程及其相关资源数据,选择功能5对当前状态进行安全检测,运行结果如图2.7所示。
在这里插入图片描述
图2.7 默认初始化安全检测截图
(2)若在t0时刻进程P1请求资源(1,0,2),是否能实施分配?
对指定进程分配资源,首先调用安全序列检测函数,检测是否存在安全序列,若存在则可以分配,打印输出安全序列,并为其分配资源,打印输出当前系统分配资源结果图。运行结果如图2.8所示。
在这里插入图片描述
图2.8 默认初始化P1请求分配资源截图
(3)在(2)的基础上,若进程P4请求资源(3,3,0),是否能实施分配?
对指定进程分配资源,首先调用安全序列检测函数,检测是否存在安全序列,不存在则不可以分配,并回收预分配的资源。运行结果如图2.9所示。
在这里插入图片描述
图2.9 默认初始化P4请求分配资源截图

2.7.2 性能分析

本次制作的银行家算法模拟系统,实现的功能比较齐全,利用的数据结构主要为二维数组和一维数组,可读性和理解性比较强。
能够成功的实现避免死锁的功能,银行家算法可以进行资源的预分配处理,但是一旦资源分配以后,系统从安全的状态变为不安全的状态就可能会导致系统报错,其本质就是:如果进程x请求分配一定的资源,系统分配之后剩余的资源无法满足之后任何一个进程的需求的话,那么该系统就会处于不安全状态。所以在请求分配资源时,设计了安全序列检测,存在安全序列则同意分配资源,否则不同意分配资源并回收预分配的资源,令系统处于安全状态。
该系统具有五大功能,分别为:初始化系统、请求分配资源、查看系统分配结果、当前状态安全性检查和退出系统。实现了较好的人机交互界面。
本系统仍然存在不足,例如实现的人机交互界面比较单一,美观性不强。系统实现的过程较为简单,部分特殊情况没有考虑到位等。这就需要在以后的学习中不断反思和完善此系统,在此过程中收获许多。

附源代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#pragma warning(disable:4996) 
#define FALSE 0
#define TRUE 1
#define M 10  //最大进程数
#define N 10  //最大资源类数
int m;//进程数
int n;//资源数目
int id; //进程ID号
int All[N];              //资源总数 
int Available[N];	//剩余资源数 
int Available_max[N];	//剩余资源数 
int MAX[M][N];		//最大需求矩阵
int Need[M][N];		//需求矩阵
int Need_t[M][N];		//需求矩阵
int Allocate[M][N];	//分配矩阵
int Request[N];		//请求资源
int Work[N];		//工作向量
int Finish[M];          //进程完成标志
int work_allocation[M][N];
void init_system();
void print_infor();
int try_allocate();
void return_back();
int is_safe();
int flag = 0;
int safe[M];
void default_system() {
	int i = 0, j = 0;
	char ch;
	int temp;
	m = 5;
	n = 3;
	All[0] = 10;
	All[1] = 5;
	All[2] = 7;
	MAX[0][0] = 7, MAX[0][1] = 5, MAX[0][2] = 3,
	MAX[1][0] = 3, MAX[1][1] = 2, MAX[1][2] = 2,
	MAX[2][0] = 9, MAX[2][1] = 0, MAX[2][2] = 2,
	MAX[3][0] = 2, MAX[3][1] = 2, MAX[3][2] = 2,
	MAX[4][0] = 4, MAX[4][1] = 3, MAX[4][2] = 3;
	Allocate[0][0] = 0, Allocate[0][1] = 1, Allocate[0][2] = 0,
	Allocate[1][0] = 2, Allocate[1][1] = 0, Allocate[1][2] = 0,
	Allocate[2][0] = 3, Allocate[2][1] = 0, Allocate[2][2] = 2,
	Allocate[3][0] = 2, Allocate[3][1] = 1, Allocate[3][2] = 1,
	Allocate[4][0] = 0, Allocate[4][1] = 0, Allocate[4][2] = 2;
	memset(Work, 0, sizeof(Work));
	memcpy(Work, Available, 3);
	/*Need*/
	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
		{
			Need[i][j] = MAX[i][j] - Allocate[i][j];
		}
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			Need_t[i][j] = Need[i][j];
		}
	}
	for (i = 0; i < n; i++) {
		int sum = 0;
		for (j = 0; j < m; j++) {
			sum = sum + Allocate[j][i];
		}
		Available[i] = All[i] - sum;
	}
	printf("系统初始化为:\n进程数目:5 \n资源总数:3 \n各类资源总数:10 5 7\n");
	printf("		 MAX  Allocation  Available\n");
	printf("		A B C	A B C	   A B C		 \n");
	printf("	P0	7 5 3	0 1 0	   ");
	for (i = 0; i < n; i++) { printf("%d ", Available[i]); }
	printf("\n	P1	3 2 2	2 0 0		 \n");
	printf("	P2	9 0 2	3 0 2		 \n");
	printf("	P3	2 2 2	2 1 1		 \n");
	printf("	P4	4 3 3	0 0 2		 \n");
	for (int t = 0; t < n; t++)
		Available_max[t] = Available[t];
	printf("\n\n\n");
}
void init_system() {
	int i=0,j=0;
	char ch;
	int temp;
	printf("请输入进程数目:\n");
	scanf("%d",&m);
	printf("请输入资源种数:\n");
	scanf("%d",&n);
	printf("请输入各类资源总数:\n");
	for(;i<n;i++)
		scanf("%d",&All[i]);
	printf("输入各进程对各资源的最大需求:\n");
	for(i=0;i<m;i++)
	{
		printf("进程P%d:\n",i);
		for(j=0;j<n;j++)
		{
			scanf("%d",&MAX[i][j]);
		}
	}
	ch = getchar();
	printf("是否输入分配矩阵?(y/n)");
	while(scanf("%c",&ch))
	{
		if(ch == 'n')
		{
			memset(Allocate,0,sizeof(Allocate));
			memset(work_allocation,0,sizeof(work_allocation));
			break;
		}
		else if(ch == 'y')
		{
			printf("请输入T时刻资源的分配矩阵:\n");
        		for(i=0;i<m;i++)
        		{
                	printf("进程P%d:\n",i);
                	for(j=0;j<n;j++)
                	{
                        scanf("%d",&Allocate[i][j]);
                	}
        		}
			break;
		}
		else
			printf("重新输入!\n");
	}
	memset(Work,0,sizeof(Work));
	memcpy(Work,Available,3);
	 /*初始时刻 Need*/
        for(i=0;i<m;i++)
            for(j=0;j<n;j++)
			{
                Need[i][j] = MAX[i][j] - Allocate[i][j];
			}
		for(int i=0;i<m;i++) {
			for(int j=0;j<n;j++) {
				Need_t[i][j]=Need[i][j];
			}
		}
		for(i=0;i<n;i++){
			int sum = 0;
			for(j=0;j<m;j++){
				sum = sum + Allocate[j][i]; 
			}
			Available[i]=All[i]-sum;
		}
		printf("当前可用的资源为:\n"); 
        for(i=0;i<n;i++){
        	printf("%d ",Available[i]);
		}	
		printf("\n"); 
}
int try_allocate()
{
	for(int i=0;i<m;i++) {
		int temp1=0;
		for(int j=0;j<n;j++) {
			if(Need[i][j]==0)
				temp1++;
		}
		if(temp1==n)
			for(int j=0;j<n;j++){
				Available[j]=Available_max[j]+Need_t[i][j];	
				Available_max[j]=Available[j];			
			}
	}
	printf("当前可用资源数:\n");
	for(int i=0;i<n;i++){
        printf("%d ",Available[i]);
	}	
	printf("\n"); 
	int i,temp,j;
	int ret = 1;
	printf("\t  MAX             Need          Allocation    \n");
	for(j=0;j<3;j++)
	{
		printf("\t  ");
		for(i = 0 ; i < n; i++)
		printf("%c  ",(char)('A'+i));
	}
	printf("\n**************************************************\n");
	for(int k=0;k<m;k++)
	{
		if(flag == 1)
			i = safe[k];
		else i = k;
		printf("P%d\t",i);
		for(j=0;j<n;j++)
			printf("%3d",MAX[k][j]);
		printf("\t");
		for(j=0;j<n;j++)
            printf("%3d",Need[i][j]);
		printf("\t");
		for(j=0;j<n;j++)
            printf("%3d",Allocate[i][j]);
		printf("\t");
		printf("\n");
	}
	printf("请输入请求进程号:\n");
	while(scanf("%d",&id))
	{
		if(id<0|id>m)
			printf("进程不存在!\n");
		else break;
	}
	printf("请输入请求资源数:\n");
	for(i=0;i<n;i++)
	{
		scanf("%d",&Request[i]);
	}
	printf("开始为进程P%d分配资源:\n",id);
	for(i=0;i<n;i++)
	{
		if(Request[i]>Need[id][i])
        {       
            printf("进程请求资源数大于所需资源数,不予分配!\n");
			ret =  0;
        }else if(Request[i] > Available[i])
		{
            printf("进程请求资源数大于可用资源数,无法分配!\n");
			ret = 0;
		}
		Available[i] -= Request[i];
        Allocate[id][i] += Request[i];
        Need[id][i] -= Request[i];
	}	
	return ret;
}
void print_infor()
{
	int i,j,k;
	printf("\t  Work             Need          Allocation    Work+Allocation    Finish\n");
	for(j=0;j<4;j++)
	{
		printf("\t  ");
		for(i = 0 ; i < n; i++)
		printf("%c  ",(char)('A'+i));
	}
	printf("\n******************************************************************************\n");
	for(k=0;k<m;k++)
	{
		if(flag == TRUE)
			i = safe[k];
		else i = k;
		printf("P%d\t",i);
		for(j=0;j<n;j++)
			printf("%3d",work_allocation[i][j]-Allocate[i][j]);
		printf("\t");
		for(j=0;j<n;j++)
                        printf("%3d",Need[i][j]);
		printf("\t");
		for(j=0;j<n;j++)
                        printf("%3d",Allocate[i][j]);
		printf("\t");
		for(j=0;j<n;j++)
                        printf("%3d",work_allocation[i][j]);
		printf("\t");
		if(Finish[i] == FALSE)
			printf("false\n");
		else printf("true\n");
	}
	printf("\n\n\n");
}
void return_back()
{
	int i,j;
	memset(Finish,0,sizeof(Finish));
	for(i=0;i<n;i++)
        {
            Available[i] += Request[i];
            Allocate[id][i] -= Request[i];
            Need[id][i] += Request[i];
        }
}
/*安全性检查函数*/
int is_safe()
{
	int i,j;
	int count = 0; 
	memset(work_allocation,0,sizeof(work_allocation));
	memset(safe,0,m);
	printf("**********Work向量**********\n");
	for(i=0;i<n;i++)
    {
        Work[i] = Available[i];
    }
	for(i=0;i<m;i++)
		Finish[i] = 0;
	for(i=0;i<m;i++)
	{
		if(Finish[i] == 0)
		{
			for(j=0;j<n;j++)
			{
				if(Need[i][j] > Work[j])
					break;
			}
			if(j == n)
			{
				printf("P%d\t",i);
				safe[count++] = i;
				for(j=0;j<n;j++)
				{
					if(count==1) {
							Work[j]=Available[j];
					        work_allocation[i][j] = Work[j]+Allocate[i][j];
					        printf("%d\t",Work[j]);
					        Work[j]=work_allocation[i][j];
					}
					else {
						Work[j]=work_allocation[safe[count-2]][j];
						work_allocation[i][j] = Work[j]+Allocate[i][j];
						printf("%d\t",Work[j]);
					}
				}
				printf("\n");
				Finish[i] = 1;  //进程i能顺利完成
				if(1)
					i = -1;//重新开始
			}
		}	
	}
	printf("\n");
	for(i=0;i<m;i++)
	{
		if(Finish[i] == 0) 
		{	
			printf("进程P%d不能顺利完成!\n",i);
			return 0;
		}
	}
	/*如果前面未返回,则存在安全序列*/
	printf("存在如下安全序列:\n");
	for(i=0;i<m; i++)
		printf("P%d ",safe[i]);
	printf("\n");
	return TRUE;
}
int main()
{
	int ret = FALSE;
	int choice;
	while(1)
	{
		printf("模拟避免进程死锁算法,选择你要进行的操作:\n");
		printf("\t  1、默认初始化系统\n");
		printf("\t  2、自定义初始化系统\n");
		printf("\t  3、请求分配资源\n");
		printf("\t  4、查看系统分配结果\n");	
		printf("\t  5、当前状态安全性检查\n");
		printf("\t  0、退出系统\n");
		scanf("%d",&choice);
		if(choice == 1)
			default_system();
		else if(choice == 2)
			init_system();
		else if(choice == 3)
		{
			if(try_allocate() == 1)
			{
				flag = is_safe();
        			if(flag == 0)
        			{
                			printf("系统不安全,不能予以分配!\n");
                			return_back();
       	 			}else{
                			printf("系统安全!分配成功!\n");
                			print_infor();
        			}
			}else{
				printf("分配失败!\n");
				return_back();
			}
		}
		else if(choice == 4)
			print_infor();
		else if(choice == 0)
			break;
		else if(choice == 5)
		{
			if((flag = is_safe()) == 0)
				printf("当前状态不安全!\n\n");
			else	
				printf("当前状态安全!\n\n");
		}
		else
			printf("输入不合法!重新输入!\n\n");
	}}
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
银行家算法是一种资源分配算法,用于避免死锁的产生。以下是用C语言实现银行家算法的代码示例: ```c #include <stdio.h> #include <stdlib.h> #define MAX_PROCESS 10 #define MAX_RESOURCE 10 int available[MAX_RESOURCE]; int max[MAX_PROCESS][MAX_RESOURCE]; int allocation[MAX_PROCESS][MAX_RESOURCE]; int need[MAX_PROCESS][MAX_RESOURCE]; int finish[MAX_PROCESS] = {0}; int safe_sequence[MAX_PROCESS]; int num_processes, num_resources; void input() { int i, j; printf("Enter number of processes: "); scanf("%d", &num_processes); printf("Enter number of resources: "); scanf("%d", &num_resources); printf("Enter available resources: "); for (i = 0; i < num_resources; i++) { scanf("%d", &available[i]); } printf("Enter maximum resources needed by each process:\n"); for (i = 0; i < num_processes; i++) { printf("Process %d: ", i); for (j = 0; j < num_resources; j++) { scanf("%d", &max[i][j]); } } printf("Enter resources allocated to each process:\n"); for (i = 0; i < num_processes; i++) { printf("Process %d: ", i); for (j = 0; j < num_resources; j++) { scanf("%d", &allocation[i][j]); need[i][j] = max[i][j] - allocation[i][j]; } } } int safety_check() { int i, j, k, count = 0, safe = 0; int work[MAX_RESOURCE]; for (i = 0; i < num_resources; i++) { work[i] = available[i]; } while (count < num_processes) { safe = 0; for (i = 0; i < num_processes; i++) { if (finish[i] == 0) { int flag = 1; for (j = 0; j < num_resources; j++) { if (need[i][j] > work[j]) { flag = 0; break; } } if (flag) { for (j = 0; j < num_resources; j++) { work[j] += allocation[i][j]; } finish[i] = 1; safe_sequence[count++] = i; safe = 1; } } } if (!safe) { break; } } if (count == num_processes) { printf("Safe sequence: "); for (i = 0; i < num_processes; i++) { printf("%d ", safe_sequence[i]); } printf("\n"); return 1; } else { printf("System is in unsafe state.\n"); return 0; } } int request_resources(int pid, int *request) { int i, j, safe = 0; for (i = 0; i < num_resources; i++) { if (request[i] > need[pid][i] || request[i] > available[i]) { printf("Error: Requested resources exceed max or available.\n"); return 0; } } for (i = 0; i < num_resources; i++) { available[i] -= request[i]; allocation[pid][i] += request[i]; need[pid][i] -= request[i]; } if (safety_check()) { printf("System is in safe state.\n"); safe = 1; } else { printf("System is in unsafe state, rolling back.\n"); for (i = 0; i < num_resources; i++) { available[i] += request[i]; allocation[pid][i] -= request[i]; need[pid][i] += request[i]; } } return safe; } int release_resources(int pid, int *release) { int i; for (i = 0; i < num_resources; i++) { if (release[i] > allocation[pid][i]) { printf("Error: Released resources exceed allocated.\n"); return 0; } } for (i = 0; i < num_resources; i++) { available[i] += release[i]; allocation[pid][i] -= release[i]; need[pid][i] += release[i]; } return 1; } int main() { int i, j, pid; int request[MAX_RESOURCE], release[MAX_RESOURCE]; input(); safety_check(); while (1) { printf("Enter process ID (or -1 to exit): "); scanf("%d", &pid); if (pid == -1) { break; } printf("Enter request: "); for (i = 0; i < num_resources; i++) { scanf("%d", &request[i]); } if (request_resources(pid, request)) { printf("Resources allocated.\n"); } else { printf("Resources not allocated.\n"); } printf("Enter release: "); for (i = 0; i < num_resources; i++) { scanf("%d", &release[i]); } if (release_resources(pid, release)) { printf("Resources released.\n"); } else { printf("Resources not released.\n"); } printf("Available resources: "); for (i = 0; i < num_resources; i++) { printf("%d ", available[i]); } printf("\n"); printf("Allocation:\n"); for (i = 0; i < num_processes; i++) { for (j = 0; j < num_resources; j++) { printf("%d ", allocation[i][j]); } printf("\n"); } printf("Need:\n"); for (i = 0; i < num_processes; i++) { for (j = 0; j < num_resources; j++) { printf("%d ", need[i][j]); } printf("\n"); } } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值