【银行家算法】操作系统课程设计


-------------------------------------------------------------------------------------------

初始化

由用户输入数据,分别对可利用资源向量矩阵AVAILABLE、最大需求矩阵MAX、分配矩阵ALLOCATION、需求矩阵NEED赋值。


银行家算法

在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁

银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。

设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。

(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。

(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],则转(3);否则,等待。

(3)系统试探分配资源,修改相关数据:

AVAILABLE[i]-=REQUEST[cusneed][i];

ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];

NEED[cusneed][i]-=REQUEST[cusneed][i];

(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。


安全性检查算法

(1)设置两个工作向量Work=AVAILABLE;FINISH;

(2)从进程集合中找到一个满足下述条件的进程,

FINISH==false;

NEED<=Work;

如找到,执行(3);否则,执行(4)

(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。

Work=Work+ALLOCATION;

Finish=true;

GOTO 2

(4)如所有的进程Finish= true,则表示安全;否则系统不安全。

                                             ――摘自《百度百科》

-------------------------------------------------------------------------------------------

C语言代码:

               -----------------头 文 件------------------  

# ifndef __BANKER_FILE__
# define __BANKER_FILE__

# define _CRT_SECURE_NO_WARNINGS 1


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

# define TRUE 1       //状态位
# define FAULSE 0      //状态位
# define PCB_NUM 5      //进程数
# define RESOURCE_NUM 5   //资源种类

size_t Menu();         //菜单
void InitPCB();        //初始化程序
size_t SafeCheck();      //安全性算法
void RequestResource();    //发出资源请求


# endif   //__BANKER_FILE__

                ----------------- 函 数 ------------------ 

# include "BANKER.h"

size_t g_max[PCB_NUM][RESOURCE_NUM] = { 0 };        //最大需求矩阵
size_t g_allocation[PCB_NUM][RESOURCE_NUM] = { 0 };    //已分配矩阵
size_t g_need[PCB_NUM][RESOURCE_NUM] = { 0 };       //需求矩阵
size_t g_available[RESOURCE_NUM] = { 0 };         //可利用资源向量

size_t g_work[RESOURCE_NUM] = { 0 };            //可利用资源数目
size_t g_finish[RESOURCE_NUM];                 //状态
size_t g_safe_order[PCB_NUM];                 //安全序列
size_t g_request[RESOURCE_NUM] = { 0 };          //请求向量
size_t g_pcb_num = 0, g_resource_type = 0;        //实际的进程数和资源种类


//菜单函数
size_t Menu()
{
	size_t choose = 0;

	printf("\t*-*-*-*-*-*- Banker's  Algorthm -*-*-*-*-*-*\n");
	printf("\t*-*-*-                                -*-*-*\n");
	printf("\t*-*-*-       1. 初始化进程            -*-*-*\n");
	printf("\t*-*-*-       2. 安全性算法            -*-*-*\n");
	printf("\t*-*-*-       3. 银行家算法            -*-*-*\n");
	printf("\t*-*-*-       0. 退      出            -*-*-*\n");
	printf("\t*-*-*-                                -*-*-*\n");
	printf("\t*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n\n");

	printf("请选择->: ");
	scanf("%d", &choose);

	return choose;
}

//检查初始化是否正确
static int _CheckInit()
{
	size_t i = 0, j = 0;

	for (i = 0; i < g_pcb_num; i++)
	{
		for (j = 0; j < g_resource_type; j++)
		{
			if (g_allocation[i][j] + g_need[i][j] > g_max[i][j])
			{
				return -1;         
			}
		}
	}
	return 1;
}

//初始化程序
void InitPCB()
{
	size_t i = 0, j = 0;
	
	printf("\n请输入进程数量和资源种类的个数:\n");
	fflush(stdin);
	scanf("%d%d", &g_pcb_num, &g_resource_type);
	printf("pcb_num = %d  resource_type = %d \n", g_pcb_num, g_resource_type);


	printf("\n输入各个进程的最大需求矩阵:\n");
	fflush(stdin);
	for (i = 0; i < g_pcb_num; i++)
	{
		printf("P[%d]:", i + 1);
		for (j = 0; j < g_resource_type; j++)
		{
			scanf("%d", &g_max[i][j]);
		}
	}
	printf("输入各个进程的已分配矩阵:\n");
	fflush(stdin);
	for (i = 0; i < g_pcb_num; i++)
	{
		printf("P[%d]:", i + 1);
		for (j = 0; j < g_resource_type; j++)
		{
			scanf("%d", &g_allocation[i][j]);
		}
	}
	printf("输入各个进程的需求矩阵:\n");
	fflush(stdin);
	for (i = 0; i < g_pcb_num; i++)
	{
		printf("P[%d]:", i + 1);
		for (j = 0; j < g_resource_type; j++)
		{
			scanf("%d", &g_need[i][j]);
		}
	}
	//求Available
	printf("输入剩余各类资源:\n");
	fflush(stdin);
	for (i = 0; i < g_resource_type; i++)
	{
		printf("P[%d]:", i + 1);
		scanf("%d", &g_available[i]);
	}

	int ret = _CheckInit();
	if (-1 == ret)
	{
		printf("初始化失败,分配矩阵与需求矩阵之和大于最大需求矩阵!\n\n");
	}
	else
		printf("初始化成功!\n\n");

}

//打印安全序列
static void _Print()
{
	size_t i = 0;

	printf("\n在该时刻存在一个安全序列: ");
	for (i = 0; i < g_pcb_num; i++)
	{
		printf("P[%d]", g_safe_order[i]);
		if (i != g_pcb_num - 1)
			printf("->");
	}
	printf("\n\n");
}

//安全性算法
size_t SafeCheck()
{
	size_t i = 0, j = 0, k = 0;
	size_t count, flag;
	size_t suffix = 0;           //安全序列的下标

	//初始化向量Work和Finish
	for (i = 0; i < g_resource_type; i++)
	{
		g_work[i] = g_available[i];
	}
	for (j = 0; j < g_pcb_num; j++)
	{
		g_finish[j] = FAULSE;
	}

	//查找安全序列
	while (1)
	{
		for (i = 0; i < g_pcb_num; i++)
		{
			count = 0;
			flag = 0;

			for (j = 0; j < g_resource_type; j++)
			{
				if (g_work[j] >= g_need[i][j])
				{
					count++;
				}
				else
					break;
			}

			//可以进行分配并完成该进程
			if ((count == g_resource_type) && (g_finish[i] != TRUE))
			{
				flag = 1;

				for (k = 0; k < g_resource_type; k++)
				{
					g_work[k] = g_work[k] + g_allocation[i][k];
				}
				g_finish[i] = TRUE;
				g_safe_order[suffix++] = i + 1;

				if (suffix == g_pcb_num)
				{
					_Print();
					return 1;
				}
			}
		}
		//遍历完之后没有符合的进程则跳出循环
		if (0 == flag)
		{
			printf("\n不存在安全序列!\n\n");
			return 0;
		}
		else
			i = 0;
	}
}

//打印分配后的进程资源表
static void _PrintPcbList()
{
	size_t i = 0, j = 0;

	printf("进程\tMax\tAllo\tNeed\tAvail\n");
	for (i = 0; i < g_pcb_num; i++)
	{
		printf("P[%d]:", i + 1);

		for (j = 0; j < g_resource_type; j++)
		{
			printf("%d ", g_max[i][j]);
		}
		printf("\t");
		for (j = 0; j < g_resource_type; j++)
		{
			printf("%d ", g_allocation[i][j]);
		}
		printf("\t");
		for (j = 0; j < g_resource_type; j++)
		{
			printf("%d ", g_need[i][j]);
		}
		printf("\t");
		if (0 == i)
		{
			for (j = 0; j < g_resource_type; j++)
			{
				printf("%d ", g_available[j]);
			}
		}
		printf("\n");
	}
	printf("\n\n");
}

//试分配
static void _TryAllocation(size_t PCB_ORDER)
{
	size_t i = 0, j = 0;
	size_t ret;

	for (i = 0; i < g_resource_type; i++)
	{
		g_available[i] -= g_request[i];
		g_allocation[PCB_ORDER][i] += g_request[i];
		g_need[PCB_ORDER][i] -= g_request[i];
	}
	
	ret = SafeCheck();
	//分配失败
	if (0 == ret)
	{
		g_need[PCB_ORDER][i] += g_request[i];
		g_allocation[PCB_ORDER][i] -= g_request[i];
		g_available[i] += g_request[i];
		printf("该分配不安全,进程P[%d]须等待!\n\n", PCB_ORDER + 1);
		
		return;
	}

	//打印分配后的进程资源表 
	_PrintPcbList();
}


//发出资源请求
void RequestResource()
{
	size_t i = 0;
	size_t PCB_ORDER = 0;

	printf("\n请输入进程名和各个资源的数量:\n");
	scanf("%d", &PCB_ORDER);
	PCB_ORDER -= 1;
	fflush(stdin);
	for (i = 0; i < g_resource_type; i++)
	{
		printf("Request_%c:", 64 + i + 1);
		scanf("%d", &g_request[i]);
	}

	
	for (i = 0; i < g_resource_type; i++)
	{
		//当Request>Need的情况
		if (g_request[i]>g_need[PCB_ORDER][i])
		{
			printf("\n需要的资源已经超出所宣布的最大值!\n\n");
			return;
		}
		//当Request>Available的情况
		if (g_request[i]>g_available[i])
		{
			printf("\n尚无足够资源,P[%d]须等待!\n\n", PCB_ORDER+1);
			return;
		}
	}
	
	//试分配
	_TryAllocation(PCB_ORDER);

}


                   -----------------主 函 数------------------ 

# include "BANKER.h"

int main()
{
	size_t ret = 0;

	while (1)
	{
		switch (ret = Menu())
		{
		case 1:
			InitPCB();
			break;
		case 2:
			SafeCheck();
			break;
		case 3:
			RequestResource();
			break;
		case 0:
			exit(EXIT_SUCCESS);
			break;
		default:
			break;
		}
	}

	system("pause");
	return 0;
}

-------------------------------------------------------------------------------------------


程序运行截图:


wKiom1aTofmCDOzvAAAsv2rE8N8613.png


wKiom1aTog-gUHDAAAAeH46xI4k302.png


wKioL1aTolTilGXbAAAoVv8YoZs936.png


wKiom1aTokejTa3nAAAeYjKT4vE038.png


wKiom1aTomGRDpVwAAAiqPkg4bE913.png


-------------------------------------------------------------------------------------------


你可能感兴趣的:(操作系统,C语言,银行家)