银行家算法c语言博客,操作系统之银行家算法

本文介绍了银行家算法在避免多进程死锁中的应用,详细阐述了死锁的四个必要条件,并提供了C语言实现的银行家算法。该算法通过检查系统是否处于安全状态来决定是否分配资源,以确保系统的安全性。在资源分配过程中,如果发现不安全状态,会进行数据重置。程序还包括用户交互,允许输入资源和进程信息,以及实时显示系统状态。
摘要由CSDN通过智能技术生成

银行家算法是一种在多道程序系统中避免多个进程并发执行所带来的死锁问题。所谓死锁(Deadlock),是指多个进程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbrace),当进程处于这种状态时,若无外力作用,他们都无法在向前推进。

避免死锁的方法:

(一)摒弃“请求和保持”条件。

(二)摒弃“不剥夺”条件,摒弃。

(三)“环路等待”条件等方法。

然而,利用银行家算法,我们可以来检测CPU为进程分配资源的情况,决定CPU是否响应某进程的的请求并为其分配资源,从而很好避免了死锁的产生。

安全状态:如果存在一个由系统中所有进程构成的安全序列P1,,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。

不安全状态:不存在一个安全序列。不安全状态不一定导致死锁。   那么什么是安全序列呢?

安全序列:一个进程序列{P1,,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j 

算法步骤:

(1)如果Requesti<or =Need,则转向步骤(2);否则,认为出错,因为它所需要的资源数已超过它所宣布的最大值。

(2)如果Request<or=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,进程必须等待。

(3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的值:

Available=Available-Request[i];

Allocation=Allocation+Request;

Need=Need-Request;

(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。

下面是具体的C语言的实现:#define _CRT_SECURE_NO_WARNINGS 1

#include 

#include 

#define SIZE 11

int available[SIZE];//可利用资源矩阵

int claim[SIZE][SIZE];//所需资源最大量矩阵

int allocation[SIZE][SIZE];//已分配资源矩阵

int need[SIZE][SIZE];//需要资源矩阵

int request[SIZE][SIZE] = { 0 };//记录某个进程申请各个资源类中的资源实例的数量

int finish[SIZE] = { 0 };//工作变量,用于判断进程是否已经执行过,初始状态全部为0,即未执行

int p[SIZE];//记录序列执行顺序

int ava;//记录系统有多少个资源类

int process;//记录进程数量

int r;//记录当前要申请资源的进程的序号

int key = 1;

void showdate();//显示资源矩阵函数

void allot();//分配函数

int init();//初始化各矩阵

int check();//检查是否为安全状态(重点)

void ava_xh()///输出资源序号

{

int k;

for (k = 0; k 

{

printf("%c ", k + 65);

}

printf("\n");

}

int main(void)

{

int t;

char ch;

while (1)//声明循环

{

system("cls");

t = init();

if (t == 1)

{

break;

}

}

do//资源申请循环

{

allot();

showdate();

printf("还要申请对进程分配资源吗?(请按Y键):");

scanf(" %c", &ch);

} while (ch == 'y' || ch == 'Y');

return 0;

}

int init()

{

int i, j;

printf("请输入资源类数量(1--%d):", SIZE);

while (1)

{

scanf("%d", &ava);

if ((ava <= SIZE) && (ava >= 1))

{

break;

}

printf("输入错误,请重新输入:");

}

printf("请依次输入各资源类的个数(中间用空格分开):\n");

while (1)

{

ava_xh();

for (i = 0; i 

{

scanf("%d", &available[i]);

}

for (i = 0; i 

{

if ((available[i]  2147483647))

{

printf("有错误的输入,重新开始吧。\n");

break;

}

}

if (i == ava)

{

break;

}

}

printf("请输入进程数量:", SIZE);

while (1)

{

scanf("%d", &process);

if ((process <= SIZE) && (process >= 1))

{

break;

}

printf("输入错误,请重新输入:");

}

printf("===============================================================\n");

for (i = 0; i 

{

//输入及检测进程所需各类资源的资源实例最大量

printf("请输入进程P(%d)所需各类资源的资源最大量Max:\n", i);

ava_xh();

for (j = 0; j 

{

scanf("%d", &claim[i][j]);

}

for (j = 0; j 

{

if (claim[i][j] > available[j])

{

printf("有数据超过系统实例最大量,退出)。\n\n\n\n");

system("pause");

getchar();

return 0;

}

}

//输入及检测进程占有各资源类中资源实例的数量

printf("请输入进程P(%d)已分配各类资源的数量Allocation:\n", i);

ava_xh();

for (j = 0; j 

{

scanf("%d", &allocation[i][j]);

}

for (j = 0; j 

{

if (claim[i][j] 

{

printf("有数据超过进程所需资源最大量。\n\n\n\n");

system("pause");

getchar();

return 0;

}

}

//输入进程还需各个资源类中资源实例的数量

printf("下面是进程P(%d)还需各个资源类中资源的数量Need:\n", i);

ava_xh();

for (j = 0; j 

{

need[i][j] = claim[i][j] - allocation[i][j];

printf("%d ", claim[i][j] - allocation[i][j]);

}

printf("\n===============================================================\n");

}

printf("\n下面是目前系统剩余的各个资源类的实例数量:\n");

ava_xh();

for (i = 0; i 

{

for (j = 0; j 

{

available[i] = available[i] - allocation[j][i];

}

printf("%d ", available[i]);

}

printf("\n===============================================================\n");

if (check() == 0)//安全检测

{

printf("安全检测失败,可能发生死锁,数据重置\n");

for (i = 0; i 

{

available[i] = available[i] + request[r][i];

allocation[r][i] = allocation[r][i] - request[r][i];

need[r][i] = need[r][i] + request[r][i];

}

}

else

{

printf("\n进程顺利执行.\n\n");

}

showdate();

return 1;

}

void allot()

{

int i, j;

printf("\n请输入当前要申请资源的进程的序号(0--%d):", process - 1);

while (1)

{

scanf("%d", &r);

if ((r <= process - 1) && (r >= 0))

{

break;

}

printf("输入错误,请重新输入:");

}

printf("请输入要申请的各个资源实例的数量:\n");

ava_xh();

for (j = 0; j 

{

scanf("%d", &request[r][j]);

}

for (i = 0; i 

{

if (request[r][i] > need[r][i])

{

printf("\n申请资源量超过所声明的最大资源需求量Max\n");

return;

}

}

for (i = 0; i 

{

if (request[r][i] > available[i])

{

printf("剩余资源实例不足,需要等待,重来一次.\n");

return;

}

}

for (i = 0; i 

{

available[i] = available[i] - request[r][i];

allocation[r][i] = allocation[r][i] + request[r][i];

need[r][i] = need[r][i] - request[r][i];

}

//int ret=check();

if (check() == 0)//安全检测

{

printf("安全检测失败,可能发生死锁,数据重置\n");

for (i = 0; i 

{

available[i] = available[i] + request[r][i];

allocation[r][i] = allocation[r][i] - request[r][i];

need[r][i] = need[r][i] + request[r][i];

}

}

else

{

int key = 0;

for (j = 0; j 

{

if (need[r][j] == 0)

{

key++;

}

}

if (key == ava)

{

for (j = 0; j 

{

available[j] += allocation[r][j];

allocation[r][j] = 0;

}

}

}printf("\n进程顺利执行.\n\n");

return;

}

int check()//检查是否是安全状态

{

int i, j, k, l = 0;

int work[SIZE] = { 0 };//工作数组

for (i = 0; i 

{

work[i] = available[i];

}

for (i = 0; i 

{

finish[i] = 0;

}

for (i = 0; i 

{

for (j = 0; j 

{

if (need[i][j] > work[j])

{

break;

}

}

if ((j == ava) && (finish[i] == 0))///寻找条件 Finish[i]=false ,每次从头开始找安全序列

{

finish[i] = 1;

for (k = 0; k 

{

work[k] = work[k] + allocation[i][k];

}

p[l] = i;//记录安全序列

l++;

//i = -1;///重置i,为了寻找安全序列

}

else

{

continue;

}

if (l == process)//可以找到安全序列,输出并结束

{

printf("\n系统安全!\n");

printf("安全序列为:");

for (k = 0; k 

{

printf("P(%d)", p[k]);

if (k != l - 1)

{

printf("-->");

}

}

return 1;

}

}

printf("\n系统不安全,不能满足你的要求!\n");

return 0;

}

void showdate()//显示现在所有数据

{

int i, j;

printf("当前所有数据!\n");

printf("\nMax\n");

printf("     ");

ava_xh();

for (i = 0; i 

{

printf("P(%d) ", i);

for (j = 0; j 

{

printf("%d ", claim[i][j]);

}

printf("\n");

}

printf("\nAllocation\n");

printf("     ");

ava_xh();

for (i = 0; i 

{

printf("P(%d) ", i);

for (j = 0; j 

{

printf("%d ", allocation[i][j]);

}

printf("\n");

}

printf("\nNeed\n");

printf("     ");

ava_xh();

for (i = 0; i 

{

printf("P(%d) ", i);

for (j = 0; j 

{

printf("%d ", need[i][j]);

}

printf("\n");

}

printf("\nAvailable\n");

ava_xh();

for (i = 0; i 

{

printf("%d ", available[i]);

}

printf("\n===============================================================\n");

printf("\n\n\n");

return;

}

初始化成功以后就开始给进程分配资源,开始调用allot()函数,银行家算法的核心之一就是进行资源类的分配,下面是分配的过程:

试分配------>进行安全性检测----->分配成功

当然,进行安全性检测后,如果不安全,我们要记得数据重置,也是资源的回收。

如果安全检测时安全的,则程序就会找出一个安全的序列,例如:p0,p1,p2,p3,p4。

此程序在找安全序列的时候每次都是从头开始找。

下面是一些输入测试:

fbe9a5e08a950f0df5e9ce4bc376a004.pngf730ce685b6374a4bb500cf3067b9000.png361e7e79cc1defd856e995df48065c8c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值