操作系统——银行家算法的模拟实现
一、实验目的
(1)理解银行家算法。
(2)掌握进程安全性检查的方法与资源分配的方法。
二、实验内容与基本要求
编制模拟银行家算法的程序,并给出一个例子验证所编写的程序的正确性。
要求例子中包含分配安全和不安全的两种情况,输出清晰明了。
三、实验报告内容
1.银行家算法和安全性检查算法原理
(1) 银行家算法
用来避免死锁。实现银行家算法,每个新进程在进入系统时它必须申明在运行过程中,可能需要的每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当某一进程请求时,系统会自动判断请求量是否小于进程最大所需,同时判断请求量是否小于当前系统资源剩余量。若两项均满足,则系统试分配资源并执行安全性检查算法。
(2) 安全性检查算法
用于检查系统进行资源分配后是否安全。在系统试分配资源后,算法从现有进程列表寻找出一个可执行的进程进行执行,执行完成后回收进程占用资源;进而寻找下一个可执行进程。当进程需求量大于系统可分配量时,进程无法执行。当所有进程均可执行,则产生一个安全执行序列,系统资源分配成功。若进程无法全部执行,即无法找到一条安全序列,所以此次分配失败。
四、程序代码
//编制模拟银行家算法的程序,并给出一个例子验证所编写的程序的正确性。
//要求例子中包含分配安全和不安全的两种情况,输出清晰明了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 300
#define maxm 300
int n, m; //n为进程的个数,m为资源类型的个数
int Available[maxm]; //可利用资源向量
int Max[maxn][maxm]; //最大需求矩阵
int Allocation[maxn][maxm]; //分配矩阵
int Need[maxn][maxm]; //需求矩阵
int Request[maxm],id; //请求向量
int ssj[maxn]; //n个进程完成情况
int work[maxm]; //工作空间
int Queue[maxn], Qi; //存安全队列
bool RN(int k){//第k个进程需求资源小于声明需求
for (int i = 0; i < m;i++){
if(Request[i]>Need[k][i]) return 0;
}
return 1;
}
bool RA(int k){//第k个进程需求资源小于可利用资源
for (int i = 0; i < m;i++){
if(Request[i]>Available[i]) return 0;
}
return 1;
}
void fenpei(int k){//分配资源
for (int i = 0; i < m;i++){
Available[i] -= Request[i];
}
for (int i = 0; i < m;i++){
Allocation[k][i] += Request[i];
}
for (int i = 0; i < m;i++){
Need[k][i] -= Request[i];
}
}
void chexiao(int k){
for (int i = 0; i < m;i++){
Available[i] += Request[i];
}
for (int i = 0; i < m;i++){
Allocation[k][i] -= Request[i];
}
for (int i = 0; i < m;i++){
Need[k][i] += Request[i];
}
}
void print(){
printf("--------------当前进程、资源情况--------------\n");
printf("\t%10s%16s%10s\n","Max","allocation","Need");
printf("进程名\t");
for (int x = 0; x < 3;x++){
printf(" ");
for (int i = 0; i < m; i++)
printf("%2c", 'a' + i);
}
printf("\n");
for (int i = 0; i < n;i++){
printf(" %d ", i);
printf(" ");
for (int j = 0; j < m; j++)
printf("%2d", Max[i][j]);
printf(" ");
for (int j = 0; j < m; j++)
printf("%2d", Allocation[i][j]);
printf(" ");
for (int j = 0; j < m; j++)
printf("%2d", Need[i][j]);
printf("\n");
}
printf("系统可利用资源:");
for (int i = 0; i < m;i++)
printf("%3d", Available[i]);
printf("\n ---------------------------------------------\n");
}
bool issafe(){//安全性算法
memset(ssj, 0, sizeof(ssj));
memcpy(work, Available, sizeof(int) * (m+1));
Qi = 0;
for (int i = 0; i < n;i++){
if(ssj[i]) continue;
int j;
for (j = 0; j < m;j++){
if(Need[i][j]>work[j])
break;
}
if(j==m){
for (j = 0; j < m;j++){
work[j] += Allocation[i][j];
}
ssj[i] = 1;
Queue[Qi++] = i;
i = -1;
}
}
for (int i = 0; i < n;i++){
if(!ssj[i]) return 0;
}
return 1;
}
int Dijkstra(){
if(issafe()==0){
printf("初始数据不安全\n");
return 1;
}
while(1){
printf("\n请输入一个请求进程的id和请求进程各个资源的量:\n");
scanf("%d", &id);
for (int i = 0; i < m;i++){
scanf("%d", &Request[i]);
}
if(RN(id)){//判断小于声明的
if(!RA(id))//大于系统资源
printf("尚无足够资源,进程须等待\n");
else{
fenpei(id);
if(issafe()){//分配资源
printf("存在一个安全队列:");
for (int i = 0; i < Qi;i++){
if(i) printf("->");
printf("%d", Queue[i]);
}
printf("\n分配成功!\n");
print();
}else{
chexiao(id);
printf("不安全,不给分配!\n");
}
}
}else{
printf("出错,所需资源超过声明最大资源\n");
}
}
}
int main()
{
printf("请输入进程数和资源数:\n");
scanf("%d %d", &n, &m);
for (int i = 0; i < n;i++){
for (int j = 0; j < m;j++)
scanf("%d", &Max[i][j]);
for (int j = 0; j < m;j++)
scanf("%d", &Allocation[i][j]);
for (int j = 0; j < m;j++)
Need[i][j] = Max[i][j] - Allocation[i][j];
}
printf("请输入系统可利用资源:\n");
for (int i = 0; i < m;i++)
scanf("%d", &Available[i]);
print();
Dijkstra();
return 0;
}
/*
请输入进程数和资源数:
5 3
7 5 3 0 1 0
3 2 2 2 0 0
9 0 2 3 0 2
2 2 2 2 1 1
4 3 3 0 0 2
请输入系统可利用资源:
3 3 2
*/
*/
五、实验结果
请输入进程数和资源数:
5 3
7 5 3 0 1 0
3 2 2 2 0 0
9 0 2 3 0 2
2 2 2 2 1 1
4 3 3 0 0 2
请输入系统可利用资源:
3 3 2
--------------当前进程、资源情况--------------
Max allocation Need
进程名 a b c a b c a b c
0 7 5 3 0 1 0 7 4 3
1 3 2 2 2 0 0 1 2 2
2 9 0 2 3 0 2 6 0 0
3 2 2 2 2 1 1 0 1 1
4 4 3 3 0 0 2 4 3 1
系统可利用资源: 3 3 2
---------------------------------------------
请输入一个请求进程的id和请求进程各个资源的量:
1 1 0 2
存在一个安全队列:1->3->0->2->4
分配成功!
--------------当前进程、资源情况--------------
Max allocation Need
进程名 a b c a b c a b c
0 7 5 3 0 1 0 7 4 3
1 3 2 2 3 0 2 0 2 0
2 9 0 2 3 0 2 6 0 0
3 2 2 2 2 1 1 0 1 1
4 4 3 3 0 0 2 4 3 1
系统可利用资源: 2 3 0
---------------------------------------------
请输入一个请求进程的id和请求进程各个资源的量:
4 3 3 0
尚无足够资源,进程须等待
请输入一个请求进程的id和请求进程各个资源的量:
0 2 3 0
不安全,不给分配!
请输入一个请求进程的id和请求进程各个资源的量:
六、结论
银行家算法实现了动态地避免死锁。每次分配试资源后执行安全性算法检测,若存在安全序列系统就是安全的,否则就是不安全会出现死锁并撤销分配。
本文作者:TTMoon
本文链接:https://www.cnblogs.com/shen75/p/18140200
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步