计算机操作系统拓展实验:银行家算法

一、实验目的

     ~~~~      编写并调试一个模拟的预防死锁的银行家调度算法程序,以加深对预防死锁的银行家调度算法的理解.

二、实验内容

  1. 调试运行银行家调度算法,给出运行结果。
  2. 找出安全序列。
  3. 申请资源分配

三、实现思路

  1. 变量初始化,接收用户输入m(进程个数),n(资源个数) ,Max(进程需要最大各类资源数),Allocation(进程已占用资源数),Need(进程还需资源数),Available(系统可利用资源);
  2. 按照银行家算法判断当前状态安全与否,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配,直到所有进程都满足资源分配则视为安全,安全给出安全序列,不安全给出提示;
  3. 如果安全,提示用户输入下一时刻进程Pk的资源请求Request(R1, … ,Rm);
  4. 接收用户输入申请分配资源的进程号和需要分配的资源数,判断该资源数是否小于Need和Available,若不满足则申请分配资源失败
  5. 按照银行家算法判断当前状态安全与否,安全给出安全序列并提示是否再次申请资源分配,如果不安全则申请分配资源失败或者无新请求退出。

四、主要的数据结构

  1. 可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果Available[j]=K,则表示系统中现有Rj类资源K个。
  2. 最大需求矩阵Max。这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
  3. 分配矩阵Allocation。这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。
  4. 需求矩阵Need。这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要R j类资源K个,方能完成其任务。

五、算法流程图

计算机操作系统拓展实验:银行家算法_第1张图片

六、运行与测试(系统运行截图)

计算机操作系统拓展实验:银行家算法_第2张图片
计算机操作系统拓展实验:银行家算法_第3张图片

七、总结

     ~~~~      通过此次试验编写并调试一个预防死锁银行家调度算法程序,掌握了如何寻找安全序列和申请分配资源的满足条件,对系统的资源调度有了更加深入的理解,同时提升了自己的编程能力和逻辑能力,得到非常大的收获。

八、代码附录

#include 

//银行家算法实现
int Max[100][100];   //进程最大需求资源
int Available[100]; //系统可利用资源
int Allocation[100][100];  //进程已占资源分配
int Need[100][100];        //进程还需资源(最大需求资源减去已占需求资源)
int Request[100][100];     //进程申请资源
int Finish[100];//存储满足状态(若满足某进程所有种类资源需求小于系统可利用资源则对应该进程置为1存储)
int p[100];//存储安全序列进程号
int m, n;   //m个进程,n个资源

//检查资源分配安全性算法
int isSafe()
{
	int i, j;
	int a = 0;
	int Work[100]; //可利用资源数组
	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] == 1)
			continue;
		else
		{
			for (j = 0; j < n; j++)
			{
				if (Need[i][j] > Work[j])//判断若每个种类需要资源大于可利用资源则结束
					break;
			}
			if (j == n)//判断每个种类需要资源都小于可利用资源
			{
				Finish[i] = 1;
				for (int k = 0; k < n; k++)
					Work[k] += Allocation[i][k];//可利用资源回收进程的释放资源
				p[a++] = i;//存储对应进程号作为后续输出安全序列号
				i = -1;//该次循环结束则i++后重新从头遍历查找Finish=0的分配资源,直至所有进程Finish=1
			}
			else continue;
		}

	}
	if (a == m) {
		printf("系统是安全的\n");
		printf("系统安全序列是:\n");
		for (i = 0; i < a; i++) {
			printf("%d", p[i]);
			if (i != a - 1)
				printf("-->");

		}
		printf("\n");
		return 1;
	}
	else {
		printf("系统是不安全的,不存在安全序列!");
		return 0;
	}

}
// 申请资源输入函数
void apply() {
	int i, j, k, fl = 0;
	while (1) {
		printf("输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n");
		scanf("%d", &k);
		printf("输入进程所请求的各个资源的数量\n");//在已占用资源的基础上申请资源
		for (i = 0; i < n; i++)
			scanf("%d", &Request[k][i]);
		while (1) {
			for (i = 0; i < n; i++) {
				if (Request[k][i] > Need[k][i])
				{
					printf("所请求资源数超过进程的需求量!\n");
					printf("请重新输入进程所需要请求的各资源的数量:\n");
					for (i = 0; i < n; i++)
						scanf("%d", &Request[k][i]);
					break;
				}
			}
			for (i = 0; i < n; i++) {
				if (Request[k][i] > Available[i])
				{
					printf("所请求资源数超过系统所有的资源数!\n");
					printf("请重新输入进程所需要请求的各资源的数量:\n");
					for (i = 0; i < n; i++)
						scanf("%d", &Request[k][i]);
					break;
				}
			}
			break;
		}
		for (i = 0; i < n; i++)
		{
			Available[i] -= Request[k][i];
			Allocation[k][i] += Request[k][i];
			Need[k][i] -= Request[k][i];
		}
		printf("此时进程已占用资源矩阵:\n");
		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				printf("%d ", Allocation[i][j]);
			}
			printf("\n");
		}
		printf("此时进程还需资源矩阵:\n");
		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				printf("%d ", Need[i][j]);
			}
			printf("\n");
		}
		printf("此时系统可利用资源:\n");
		for (i = 0; i < n; i++)
			printf("%d ", Available[i]);
		printf("\n");
		if (isSafe())
			printf("同意分配请求\n");
		else
		{
			printf("不同意分配请求\n");
			for (i = 0; i < n; i++)
			{
				Available[i] += Request[k][i];
				Allocation[k][i] -= Request[k][i];
				Need[k][i] += Request[k][i];
			}
		}
		for (i = 0; i < m; i++)
			Finish[i] = 0;
		char Flag;
		printf("是否再次请求分配?是请按Y,否请按N\n");
		while (1)
		{
			getchar();
			scanf("%c", &Flag);
			if (Flag == 'Y' || Flag == 'N') {
				break;

			}
			else
			{
				printf("请按要求重新输入:\n");
				continue;
			}
		}
		if (Flag == 'Y')
			continue;
		else break;
	}
}

int main()
{
	int i, j, k;
	char flag;
	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("输入每个进程已经占用的各类资源数,按照%d*%d矩阵输入\n", m, 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 < m; i++) {
		for (j = 0; j < n; j++) {
			printf("%d ", Need[i][j]);
		}
		printf("\n");
	}
	printf("请输入系统各类资源可利用的数目:\n");
	for (i = 0; i < n; i++)
		scanf("%d", &Available[i]);
	if (isSafe()) {
		printf("是否需要指定进程申请资源分配?是请按Y,否请按N\n");
		while (1)
		{
			getchar();
			scanf("%c", &flag);
			if (flag == 'Y' || flag == 'N') {
				break;

			}
			else {
				printf("请按要求重新输入:\n");
				continue;
			}
		}
		if (flag == 'Y') {
			apply();
		}
	}
	else {
		return 0;
	}
	return 0;

}

你可能感兴趣的:(计算机操作系统实验)