操作系统(进程死锁)

一、实验目的

1.理解银行家算法。
2.掌握进程安全性检查的方法及资源分配的方法。

二、实验内容

编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性。
例如某系统有A、B、C、D4类资源共5个进程(PO、P1、P2、P3、P4)共享,
各进程对资源的需求和分配情况如下图所示。
对表中各进程对资源的需求和分配情况表

在这里插入图片描述
现在系统中A、B、C、D4类资源分别还剩1、5、2、0个,请按银行家算法回答下列问题:

  1. 现在系统是否处于安全状态? 答:安全
  2. 如果现在进程Pl提出需要(0、4、2、0)个资源的请求,系统能否满足它的请求?
    答:不能

数据结构

代码如下(示例):

int Avaliable[100];//可利用最大资源数组 
int Max[50][100];//最大需求矩阵
int Allocation[50][100]; //分配最大矩阵
int Need[50][100];//需求矩阵
int Request[50][100];//请求资源数组 
int Finish[50]; //当前资源数是否结束 
int p[50];//存放记录序列
int m;//m个进程
int n;//n个资源

void Show(int n, int m);//定义显示进程资源函数Show

程序流程图:

在这里插入图片描述
安全性检查算法程序流程图

银行家算法程序流程图
银行家算法程序流程图

代码走起:

#include <iostream>
#include<time.h>

int Avaliable[100];//可利用最大资源数组 
int Max[50][100];//最大需求矩阵
int Allocation[50][100]; //分配最大矩阵
int Need[50][100];//需求矩阵
int Request[50][100];//请求资源数组 
int Finish[50]; //当前资源数是否结束 
int p[50];//存放记录序列
int m;//m个进程
int n;//n个资源

void Show(int n, int m);//定义Show函数 

void Time()
{
	time_t t;//将t声明为时间变量
    struct tm *p;//struct tm是一个结构体,声明一个结构体指针
    time(&t);
    p=localtime(&t);//获得当地的时间
    int s = 7;
    int k = 7;
    int sum;
    sum = s * k;
    printf("**********%d**********\n",sum);
    printf("        学号\n");
    printf("         姓名\n");
    printf("----------分割线----------\n");
    printf("\n");
    printf("操作系统实验展示于%d年%d月%d日 %d时%d分%d秒\n",1900 + p -> tm_year, 1 + p -> tm_mon, p -> tm_mday, p -> tm_hour, p -> tm_min, p -> tm_sec);
    //输出当前本地的时间 
}

//初始化 
int state()
{
	int i = 0;
	int j = 0;
	printf("----------分割线----------\n");
	printf("\n");
	
	printf("********银行家算法进程演示********\n");
	printf("请输入总进程数:\n");
	scanf("%d",&m);
	
	printf("请输入总资源种类数:\n");
	scanf("%d",&n);
	
	printf("请输入每个进程最多需要的资源数,按照%d*%d的矩阵输入:\n",m,n);
	for(i = 0; i < m; i++)
		for(j = 0; j < n; j++)
		scanf("%d",&Max[i][j]);
		printf("你输入的最大需求资源矩阵是!!\n");
		for(i = 0; i < m; i++)
		{
			printf("%d",i);
			for(j = 0; j < n; j++)
			printf("  %d",Max[i][j]);
			printf("\n");
		}
		
		printf("请输入每个进程已经分配的资源数,按照%d*%d的矩阵输入:\n",m,n);
//		for(i = 0; i < m; i++)
//		for(j = 0; j < n; j++)
//		scanf("%d",&Allocation[i][j]);
//		printf("你输入的已分配的资源矩阵是!\n");
//		for(i = 0; i < m; i++)
//		{
//			printf("%d",i);
//			for(j = 0; j < n; j++)
//			printf("  %d",Allocation[i][j]);
//			printf("\n");
//		}
//		printf("根据你的输入,你的需要矩阵是:\n");
//		for(i = 0; i < m; i++)
//			{
//			printf(" ",i); 
//			for(j = 0; j < n; j++)
//			printf("     %d",Need[i][j]);
//			printf("\n");
//			}
//		for(i = 0; i < m; i++)
//		for(j = 0; j < n; j++)
//		{
//			scanf("%d",&Allocation[i][j]);
//			Need[i][j] = Max[i][j] - Allocation[i][j];
//			scanf("%d",&Need[i][j]);
//			printf("根据你的输入,你的需要矩阵是:\n");
//		
	for(i = 0; i < m; i++)
	for(j = 0; j < n; j++)
	{
		scanf("%d",&Allocation[i][j]);
		Need[i][j] = Max[i][j] - Allocation[i][j];
		
		if(Need[i][j] < 0)
		{
			printf("你输入的第%d个进程拥有的第%d个资源出现错误,请重新输入:\n",i+1,j+1);
			j--;
			continue;
		}
	}
	printf("请输入各个资源现有的数目!\n");
	
	for(i = 0; i < n; i++)
		scanf("%d",&Avaliable[i]);
}

//安全检测,查看系统是否安全 
int Safe()
{
	int i = 0;
	int j = 0;
	int l = 0;
	int k = 0;
	int Work[100];
	
	for(i = 0; i < n; i++)
		Work[i] = Avaliable[i];//工作的资源等于可利用最大资源数组
		 
	for(i = 0; i < m; i++)
		Finish[i] = 0;//记录每个进程是否安全 
	
	while(l < m) //执行m次 
	{
		int index = l;//判断系统是否安全 
		for(i = 0; i < m; i++)
		{
			if(Finish[i] == 1)//进程安全则继续执行 
			continue;
			for(j = 0; j < n; j++)
				if(Need[i][j] > Work[j])
				break;
			if(j == n)
			{
				Finish[i] = 1;
				for(k = 0; k < n; k++)
				Work[k] += Allocation[i][k];//把放出的资源当成现有的资源
				p[l++] = i;//记录完成的进程号 
			}
			else 
			continue;//超过继续循环下一个进程 
		}
		if(l == index)
		{
			printf("系统是不安全!!!!\n");
			return 0;
		 } 
	}
	printf("系统是安全的:\n");
	printf("安全系列为:\n"); 
	
	for(i = 0; i < l; i++)
	{
		printf("%d",p[i]);
		if(i != l - 1)
		printf("--->");
	}
	printf("\n");
	return 1;
}

//银行家算法 
int Blank()
{
	int i = 0;
	int flag = 0;
	int mi = 0;
	char YesOrNo;//判断命令字符
	
	while(1)
	{
		Show(n,m);
		printf("\n");
		
		while(true)
		{
			printf("请输入当前要申请的进程号(注:第1个进程号为0,第二个进程号为1,以此类推)\n");
			scanf("%d",&mi);
			
			if(mi > m)
			{
				printf("不存在该进程,请用户重新输入:\n");
				continue;
			}
			printf("请输入该进程所需要的各个资源数:\n");
			
			for(i = 0; i < n; i++)
			scanf("%d",&Request[mi][i]);
			
			for(i = 0; i < n; i++)
			{
				if(Request[mi][i] > Need[mi][i])
				{
					printf("你输入的请求数超出进程的需求量,请重新输入:\n");
					continue;
				}
				if(Request[mi][i] > Avaliable[i])
				{
					printf("你输入的请求数超过系统现有资源数,请用户重新输入:\n");
					continue;
				}
			}
			break;
		}
		
		for(i = 0; i < n; i++)
		{
			Avaliable[i] -= Request[mi][i];//系统可用资源减去申请了的
			Allocation[mi][i] += Request[mi][i];//当前分配给各个进程的各种资源数量增加
			Need[mi][i] -= Request[mi][i];//当前该进程还需要分配的资源减少
		}
		if(Safe())
		printf("同意分配请求!!!\n");
		
		else
		{
			printf("你的请求被拒绝!!!!\n");//资源还给系统
			 
			for(i = 0; i < n; i++)
			{
				Avaliable[i] += Request[mi][i];
				Allocation[mi][i] -= Request[mi][i];
				Need[mi][i] += Request[mi][i];
			} 
		}
		
		for(i = 0; i < n; i++)
		{
			if(Need[mi][i] <= 0)
			flag++;
			
			if(flag == n)
			{
				for(i = 0; i < n; i++)
				{
					Avaliable[i] += Allocation[mi][i];
					Allocation[mi][i] = 0;
					Need[mi][i] = 0;
				}
				printf("线程%d的资源已经被释放\n",mi);
				flag = 0;
			}
			for(i = 0; i < n; i++)
			Finish[i] = 0;
			printf("你是否需要继续申请资源分配?是,请选择Y/y,否,请选择N/n退出程序\n");
			scanf("%d",&YesOrNo);
			YesOrNo = getchar();
			if(YesOrNo == 'Y' || YesOrNo == 'y')
			continue;
			else
			if(YesOrNo == 'N' || YesOrNo == 'n')
//			if(gatchar())
			return 0;
//			if(YesOrNo == 'N' || YesOrNo == 'n')
//		{
//			break;
//			}
		}
	} 	
	
}

void Show(int n,int m)
{
	int i = 0;
	int j = 0;
	
	printf("系统可用的资源数为:");
	for(j = 0; j < n; j++)
	printf("%d-->",Avaliable[j]);
	printf("\n");
	
	printf("各个进程还需要的资源量:\n");
	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");
	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");
}

int main()
{
	Time();
	state();
	Safe();
	Blank();
}


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又菜又爱巻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值