C语言实现的操作系统银行家算法
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实现的操作系统银行家算法相关的知识,希望对你有一定的参考价值。
文章目录
一、银行家算法
银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
二、方案分析
模拟实现银行家算法对系统资源进行分配,以防止死锁的出现。本课题肯定不可能实现对实际操作系统的资源管理,而是通过对模拟资源数据的处理,检测银行家算法在防止死锁出现的作用。先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。若请求合法,则进行试分配。最后对试分配后的状态调用安全性检查算法进行安全性检查。若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
三、开发环境
- Windows操作系统
- VS 2017
- C语言
四、设计思想及实验步骤
4.1 设计思想
先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。若请求合法,则进行试分配。最后对试分配后的状态调用安全性检查算法进行安全性检查。若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
4.2 银行家算法中的数据结构
可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态改变。如果Available[j]=K,则表示系统中现有Rj类资源K个。
最大需求矩阵Max。这是一个 的矩阵,它定义了系统中 个进程中的每一个进程对 类资源的最大需求。如果Max[I,j]=K,则进程i需要Rj类资源的最大数目为K。
分配矩阵Allocation。这也是一个 的矩阵,它定义了系统中每一类资源当前已分配给每一个进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已经分得Rj类资源的数目为K。
需求矩阵Need。这也是一个 的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成任务。
即:
int M ; // 总进程数
int N ; // 资源种类
int ALL_RESOURCE[W]; // 各种资源的数目总和
int Max[W][R]; // 最大需求矩阵,M个进程对N类资源最大资源需求
int Available[R]; // 可利用资源向量,
int Allocation[W][R];// 分配矩阵,各个进程M已经得到N类资源的资源数
int Need[W][R]; // M个进程还需要N类资源的资源量
int Request[R]; // 进程的请求资源个数
以上三个矩阵间存在下述关系:
Need[i,j] = Max[i,j] - allocation[i, j]
4.3 银行家算法bank()
设Request i是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。发出请求后,系统按下述步骤进行检查:
-
(1)检查申请量是否不大于需求量。如果
Request i[j]<=Need[i,j]
,便转向步骤(2);否则认为出错,因为他所需要的资源数已经超过它所宣布的最大值。 -
(2)检查申请量是否小于系统中的可利用资源数量。如果
Requesti[j]<=Available[i,j]
,便转向步骤(3);否则认为尚无足够资源,Pi必须等待。 -
(3)若以上两个条件都满足,则系统试探着将资源分配给申请的进程,并修改下面数据结构中的数值:
Available[j]=Available[j]-Request[j]; Allocation[k][j]=Allocation[k][j]+Request[j]; Need[k][j]=Need[k][j]-Request[j];
-
(4)试分配后,系统执行安全性算法,调用safe()函数检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程,以完成本次分配,并将安全序列打印出来;否则本次试探分配作废,恢复原来的资源分配状态,让该进程等待。
4.4 安全性算法safe()
(1)设置两个向量
- 工作向量:
- Work,它表示系统可提供给进程继续运行所需要的各类资源数目,它含有m个元素,在执行安全性算法开始时,Work: =Available
- Finish,它表示系统是否有足够资源分配给进程,使之运行完成。开始时先做Finish[i]:=false;当有足够的资源分配给进程时,再令Finish[i]:=true
(2)从进程集合中找到一个满足下述条件的进程
- Finish[i]:=false;
- Need[i,j]<=Work[j];若找到,执行步骤(3),否则,执行步骤(4)
(3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行
Work[j] = Work[j] + Allocation[i,j];
Finish[i] = true;
go to step 2;
(4)如果所有的进程Finish= true都满足,则表示系统处于安全状态;否则系统处于不安全状态
五、程序的基本结构框图和流程图
5.1 程序结构功能图
5.2 流程图
六、源代码
#include<stdio.h>
// 预处理
#define FALSE 0
#define TRUE 1
#define W 10
#define R 10
int safe_queue[10];
static int cnt = 0;
int M; // 进程数
int N; // 资源种类数
int all_resource[W]; // 各种资源数目
int max[W][R]; // 最大需求矩阵,M个进程对N类资源最大资源需求
int available[R]; // 可利用资源数
int allocation[W][R]; // 已分配矩阵,各个进程M得到N类资源的资源数
int need[W][R]; // M个进程还需要N类资源的数目
int request[R]; // 进程请求的资源个数
void display(); // 项目信息
void show(); // 显示当前各进程的分配和需求信息
void fenpei(int k); // 分配资源
void huishou(int k); // 上一个进程结束释放所得资源后,系统重新获得的可利用资源huishou
bool safe(); // 安全性算法
void bank(); // 银行家算法
int main()
int i = 0, j = 0, p;
display();
printf("------------------------------------------------\\n\\n");
// 信息输入
printf("请输入进程数:");
scanf("%d", &M);
printf("请输入资源种类:");
scanf("%d", &N);
printf("请输入%d个各类资源总数:", N);
for (i = 0; i < N; i++)
scanf("%d", &all_resource[i]);
printf("请输入%d个各进程所需要的各类资源的最大数量(M*N矩阵输入):\\n", M*N);
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
do
scanf("%d", &max[i][j]);
if (max[i][j] > all_resource[j])
printf("占有资源超过了声明的该资源总数,请重新输入\\n");
while (max[i][j] > all_resource[j]);
printf("请输入%d个各进程已经分配的各类资源的数量:\\n", M*N); //各进程已经分配的各类资源的数量
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
do
scanf("%d", &allocation[i][j]);
if (allocation[i][j] > max[i][j])
printf("已分配的资源超过了声明的最大资源,请重新输入\\n");
while (allocation[i][j] > max[i][j]);
// 需要资源的数目=最大-已分配
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
need[i][j] = max[i][j] - allocation[i][j];
// 可利用资源数=总的-所有进程用的
for (j = 0; j < N; j++)
p = all_resource[j];
for (i = 0; i < M; i++)
p = p - allocation[i][j]; // 减去已经被占据的资源
available[j] = p;
if (available[j] < 0)
available[j] = 0;
show(); // 显示当前各进程的分配和需求信息
bank(); // 调用银行家算法进行计算
return 0;
// 打印项目信息
void display()
printf("\\n\\n\\n ------------------------------------------\\n");
printf(" | | \\n");
printf(" | 题目:银行家算法实现 | \\n");
printf(" | | \\n");
printf(" -------------------------------------------\\n");
// 显示当前各进程的分配和需求信息
void show()
int i, j;
printf("\\n-----------------------------------------------------------------\\n");
printf("各种资源的总数量:\\n"); //各种资源的总数量
for (j = 0; j < N; j++)
printf(" %d", all_resource[j]);
printf("\\n-----------------------------------------------------------------\\n");
printf("目前各种资源可利用的数量为:\\n");//各种资源的总数量减去已分配后剩余的资源量
for (j = 0; j < N; j++)
printf(" %d", available[j]);
printf("\\n-----------------------------------------------------------------\\n");
printf("各进程还需要的资源数量:\\n"); //各进程还需要的资源数量
for (i = 0; i < N; i++)
printf(" 资源%d", i);
printf("\\n");
for (i = 0; i < M; i++)
printf("进程%d ", i);
for (j = 0; j < N; j++)
printf("%d ", need[i][j]);
printf("\\n");
printf("\\n");
printf("-----------------------------------------------------------------\\n");
printf("各进程已经得到的资源量: \\n");//打印各进程已经得到的资源量
for (i = 0; i < N; i++)
printf(" 资源%d", i);
printf("\\n");
for (i = 0; i < M; i++)
printf("进程%d ", i);
for (j = 0; j < N; j++)
printf("%d ", allocation[i][j]);
printf("\\n");
printf("\\n");
// 分配资源
void fenpei(int k)
int j;
// 系统试探着把资源分配给进程Pi,并修改下面的数据结构fenpei
for (j = 0; j < N; j++)
available[j] = available[j] - request[j];
allocation[k][j] = allocation[k][j] + request[j];
need[k][j] = need[k][j] - request[j];
// 上一个进程结束释放所得资源后,系统重新获得的可利用资源
void huishou(int k)
int j;
for (j = 0; j < N; j++)
available[j] = available[j] + request[j];
allocation[k][j] = allocation[k][j] - request[j];
need[k][j] = need[k][j] + request[j];
/*
安全性算法,设置两个向量Work和Finish.
Work:表示系统可提供给进程继续运行所需的各类资源数目;
Finish:表示系统是否有足够的资源分配给进程。
*/
bool safe()
int Work[R], Finish[W]; // 设置两个向量Work和Finish.
int i, j, m;
for (j = 0; j < N; j++)
Work[j] = available[j]; // 在执行安全算法之前,初始化
for (i = 0; i < M; i++)
Finish[i] = FALSE; // 系统初始化,将各进程的初始完成状态设置为FALSE
for (i = 0; i < M; i++) // M进程
for (j = 0; j < N; j++) // j类资源
for (m = 0; m < M; m++) // 对M线程都对应查M次
// 如果m进程还未完成 且 所需小于系统可用的,那么试分配资源
if (Finish[m] == FALSE && need[m][j] <= Work[j])
Work[j] = Work[j] + allocation[m][j]; // 该进程完成后,系统可用的变为原来的加上该进程已分配的
Finish[m] = TRUE; // 当有足够的资源分配给进程时,设置为TRUE
safe_queue[cnt] = m; // 记录安全进程序列
cnt++;
// 判断系统安全性
for (i = 0; i < M; i++)
if (Finish[i] == FALSE)
printf("\\n经安全性算法检查,此时系统处于不安全状态! 本次分配不成功!!!\\n\\n");
return 1;
else
printf("\\n经安全性算法检查,此时系统安全,分配成功。\\n");
printf("此时系统的安全序列是:\\n");
for (i = 1; i < cnt; i++)
printf("%d ", safe_queue[i]); // 打印安全序列
printf("\\n");
return 0;
return 1;
// 银行家算法进行计算
void bank()
int i = 0, j = 0;
char flag = 'Y';
while (flag == 'Y' || flag == 'y')
i = -1;
while (i < 0 || i >= M)
printf("-----------------------------------------------------------------\\n");
printf("请输入申请资源的进程号:\\n"); //进程Pi发出请求
scanf("%d", &i);
if (i < 0 || i >= M)
printf("对不起,输入的进程号不存在,请重新输入!\\n");
printf(" 请输入进程%d申请各类资源的数量:\\n", i);
for (j = 0; j < N; j++)
printf("资源%d: ", j);
scanf("%d", &request[j]);
// 若请求的资源数大于进程还需要i类资源的资源量j
if (request[j] > need[i][j])
printf("进程%d申请的资源数大于进程%d还需要%d类资源的数量!\\n", i, i, j);
printf("若继续执行系统将处于不安全状态!\\n");
flag = 'N';
break;
else
// 若请求的资源数大于可用资源数
if (request[j] > available[j])
printf(" 进程%d申请的资源数大于系统可用%d类资源的数量!\\n", i, j);
printf(" 若继续执行以上是关于C语言实现的操作系统银行家算法的主要内容,如果未能解决你的问题,请参考以下文章