-------------------------------------------------------------------------------------------
银行家算法
在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程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)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
安全性检查算法
(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; }
-------------------------------------------------------------------------------------------
程序运行截图:
-------------------------------------------------------------------------------------------