-------------------------------------------------------------------------------------------
初始化
由用户输入数据,分别对可利用资源向量矩阵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;
}
-------------------------------------------------------------------------------------------
程序运行截图:
-------------------------------------------------------------------------------------------
转载于:https://blog.51cto.com/814193594/1733939