【操作系统】银行家算法实现(C语言)

注意:本人编码水平很菜。算是自己的一个总结。可能会有我还没有发现的bug。如果有人发现后可以指出,不胜感激。

1.银行家算法:

我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。

为保证资金的安全,银行家规定: (1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客; (2)

顾客可以分期贷款,但贷款的总数不能超过最大需求量; (3)

当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款; (4)

当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.

操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。 ---------引用自百度百科

2.简单来说:系统中的资源是有限的。不足以一下子把所有进程所需的资源都分配。

我们需要做的就是在有限的资源下,是否有一个分配顺序,可以使得全部进程都可以获得资源并运行,如果可以则返回一个安全队列,如果不可以,则说明有风险,系统可能会陷入死锁。

3.数据结构

1)可利用资源向量Available

是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。

2)最大需求矩阵Max

这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵Allocation

这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的

数目为K。 4)需求矩阵Need。

这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。

4.举个例子:

系统总资源是(9,3,6)

max Allocation need Available finished
R1 R2 R3 R1 R2 R3 R1 R2 R3 R1 R2 R3
p1 3 , 2 , 2 1 ,0 ,0 2 , 2 , 2 6,1,4 (9,3,6) True
p2 6 ,1 ,3 5 ,1 ,2 1 , 0 ,1 0,1,0 (6,2,3) True
p3 3 ,1 ,4 2 , 1 , 1 1 ,0 , 3 5,2,0 (8,3,4) Ture
p4 4 ,2 , 2 0 ,0, 2 4 ,2 ,0 4,1,4 (8,3,6) True

分配给p2(1,0,1) 目前系统可用资源 1,1,1

1.此时p2仍然需要1,0,1 ,可以满足p2所需资源 。p2完成后释放资源

此时系统资源总数为(6,2,3)

2.分配给p3,系统资源剩(5,2,0)。p3完成后释放资源,

此时的资源总数为(8,3,4)

3.分配给p4,系统资源剩(4,1,4)。P4完成后释放资源,此时系统资源总数为(8,3,6)

4.分配给p1,系统资源(6,1,4),p1完成后释放资源,此时系统资源总数为(9,3,6)

全部进程执行完毕。

安全序列为:p2---->p3--->p4---->p1

运行截图 :

5.代码段

#include<stdio.h>
#include<stdlib.h> #define Num_Dev 3 // 每个进程所需的设备的种类数量
#define Max 10 //可容纳的最多的进程数量 int Max_Need_Dev [Max][Num_Dev]; //所有进程所需要的设备的最大数目
int Allocation_Dev [Max][Num_Dev]; //所有进程已经分配到的设备的数目
int Need_Dev [Max][Num_Dev]; //所有进程还需要的设备的数目 int current_Available_Dev[Max][Num_Dev]; //记录分配完之后,此时系统的可用资源数目(因为假如会产生安全队列,那么有多少个进程就会产生多少次这样的当前分配后的可用资源数目)
int current_recycle_Dev[Max][Num_Dev]; //记录回收完之后,系统中各个设备的数目 int system_Dev[Num_Dev]; //系统中所拥有的各类设备的数量
int Available_Dev [Num_Dev]; //系统中剩余的资源数量
int finish [Max]; //存存放所有进程是否已经运行完毕。 int quene[Max]; //假设不会出现死锁,那么用于存放安全队列。 即记录每个进程的下表。 int num; // 进程的名字 void init(){
printf("请输入系统中各类资源的数目总和:\n");
for (int i = 0; i < Num_Dev; i++)
{
scanf("%d",&system_Dev[i]);
Available_Dev[i] = system_Dev[i];
printf("%d\t",Available_Dev[i]);
} printf("\n"); printf("请输入进程的数量:\n");
scanf("%d",&num);
printf("\n"); printf("请输入各个进程运行所需要全部设备的数量:\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
scanf("%d",&Max_Need_Dev[i][j]);
}
}
printf("\n"); printf("请输入各个进程已经分配到的设备的数目:\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
scanf("%d",&Allocation_Dev[i][j]);
Available_Dev[j] = Available_Dev[j] - Allocation_Dev[i][j]; //计算系统中剩余设备的数目
}
} printf("\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
Need_Dev[i][j] = Max_Need_Dev[i][j] - Allocation_Dev[i][j]; //计算各个进程依然所需要的各个设备的数目
}
}
for (int i = 0; i < num; i++)
{
finish[i] = 0;
quene[i] = -1;
} }
void print(){
printf("进程ID\t|\tMax\t|\tAllocat\t|\tNeed\t|\tAvail\t|\t\tfinish\n");
for (int i = 0; i < num; i++)
{
printf("%d\t|\t",quene[i]);
printf("%d,%d%,%d\t|\t%d,%d%,%d\t|\t%d,%d%,%d\t|\t%d,%d%,%d (%d,%d,%d)\t|\t%d\\",Max_Need_Dev[i][0],Max_Need_Dev[i][1],Max_Need_Dev[i][2],Allocation_Dev[i][0],Allocation_Dev[i][1],Allocation_Dev[i][2],Need_Dev[i][0],Need_Dev[i][1],Need_Dev[i][2],current_Available_Dev[i][0],current_Available_Dev[i][1],current_Available_Dev[i][2],current_recycle_Dev[i][0],current_recycle_Dev[i][1],current_recycle_Dev[i][2],finish[i]);
printf("\n");
}
} int conpare(int *p){ //判断当前可用设备的数目是否可以满足所传入的进程的要求
for(int j = 0;j < Num_Dev; j ++){
if(*(p+j) > Available_Dev[j] ){
return 0;
}
}
return 1;
} void recycle(int *p){ //若一个进程运行完毕,回收已经分配给它的设备
for (int i = 0; i < Num_Dev; i++)
{
Available_Dev[i] += *(p+i);
}
} int allocation(){
int flag = 0;
int count = 1; //判断死锁。就是遍历一遍之后没有进程可以运行。
int i = 0; //判断是哪一个进程
int index = 0; //用于记录安全队列的下表
int max_times; //因为有num个变量, 所以假如有安全队列,最多就是寻找num的平方次
while (1)
{
max_times ++;
if(conpare(Need_Dev[i])==1&&finish[i] == 0){
count = 0;
finish[i] = 1; //表示该进程获得资源后运行完毕
for (int j = 0; j < Num_Dev; j++) // 让进程获取剩余设备 即
{
Allocation_Dev[i][j] += Need_Dev[i][j]; //1.让进程已经分配的设备数目加上它仍然需要的
Available_Dev[j] -= Need_Dev[i][j]; //2.系统中目前可用的设备数目减去进程需要的 current_Available_Dev[i][j] = Available_Dev[j]; //记录分配完之后,此时系统的可用资源数目(因为假如会产生安全队列,那么有多少个进程就会产生多少次这样的当前分配后的可用资源数目)
} recycle(Max_Need_Dev[i]); // 回收资源
for (int j = 0; j < Num_Dev; j++)
{
current_recycle_Dev[i][j] += Available_Dev[j];
} quene[index] = i;
index ++;
if(index == num ){
flag = 1;
printf("安全队列已经返回了。快去看看吧!\n");
break;
}
}
if(count == num){
printf("会发生死锁。无安全队列。。。。。。\n");
break;
}
if(i == num - 1){
i = 0;
continue;
}
if(max_times == num*num){
printf("全部可能已经执行完毕,无安全队列。。。。。。\n");
break;
}
count ++;
i ++;
}
return flag;
} int main(void ){
init();
int flag = allocation();
print();
if(flag == 1){
for (int i = 0; i < num; i++)
{
printf("%d--->",quene[i]);
} }
printf("\n");
system("pause");
}

【操作系统】银行家算法实现(C语言)的更多相关文章

  1. C语言实现 操作系统 银行家算法

    /**************************************************** 银行家算法 算法思想: 1. 在多个进程中,挑选资源需求最小的进程Pmin. 可能存在多类资 ...

  2. 操作系统——银行家算法(Banker's Algorithm)

    之前写过一篇关于死锁和银行家算法的详细描述的博客https://www.cnblogs.com/wkfvawl/p/11598647.html 写这篇博客的目的,主要是详细讲解一下银行家算法以及代码的 ...

  3. 操作系统,银行家算法模拟实现(Windows 环境 C++)

    计算机操作系统课设需要,写了两个下午的银行家算法(陷在bug里出不来耽误了很多时间),参考计算机操作系统(汤子瀛) 实现过程中不涉及难度较大的算法,仅根据银行家算法的思想和步骤进行实现.以下为详细步骤 ...

  4. python模拟银行家算法

    前言: 大二第一学期学习了操作系统,期末实验课题要求模拟算法.遂根据自己学习的python写下此文.以此锻炼自己编码能力.虽说是重复造轮子,但还是自己的思路体现 代码及注释如下(银行家算法不再赘述): ...

  5. 预防和避免死锁的方法及银行家算法的java简单实现

    预防死锁 (1) 摒弃"请求和保持"条件 基本思想:规定所有进程在开始运行之前,要么获得所需的所有资源,要么一个都不分配给它,直到所需资源全部满足才一次性分配给它. 优点:简单.易 ...

  6. C程序模拟实现银行家算法

    C程序模拟实现银行家算法 上周又做操作系统实验,题目是用程序模拟实现银行家算法,写了半天还真有点晕,主要是因为想尽可能符合课本上的描述,所以写出来的程序就比较恶心了,好了,银行家算法就不多说了,不了解 ...

  7. 银行家算法之JavaScript实现

    上学期有个课程叫做操作系统,期末的时候这课程还有个课程设计,其中有个题目叫做银行家算法. 什么是银行家算法我就不解释了! 看着同学们的设计,大同小异甚至前篇一律. 清一色的控制台程序,清一色的蛋疼输入 ...

  8. java面试题之死锁产生的条件,以及如何避免死锁,银行家算法,产生死锁后如何解决(阿里面试题)

    死锁产生的四个必要条件: 互斥:一个资源每次只能被一个进程使用(资源独立) 请求与保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放(不释放锁) 不剥夺:进程已获得的资源,在未使用之前,不能强行 ...

  9. C# Math.Round()的银行家算法

    可能很多人都跟我一样,都只知道Math.Round()是C#中用来做四舍五入,保留指定小数位的 但实际上它并不是真正的四舍五入,而是银行家算法的四舍六入五取偶 事实上这也是IEEE的规范,因此所有符合 ...

随机推荐

  1. EXPECT交互式批量上传公钥

    EXPECT交互式批量上传公钥 # vim key.sh #/bin/bash Public_Key() { [ ! -f /usr/bin/expect ] && yum insta ...

  2. 关于“Cannot resolve table 'user'”报错的问题解决

    springboot+vue建立映射时,后端引用@Table(name="user") 来对应表名 user,但引用后报错"Cannot resolve table 'u ...

  3. oracle ql/sql 相关语法解析

    这篇文章主要介绍了Oracle中游标Cursor基本用法详解,还是比较全面的,具有一定参考价值,需要的朋友可以了解下.   查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELE ...

  4. [CF160D]Edges in MST (最小生成树+LCA+差分)

    待填坑 Code //CF160D Edges in MST //Apr,4th,2018 //树上差分+LCA+MST #include<cstdio> #include<iost ...

  5. [Luogu P2278] [HNOI2003]操作系统

    题面 传送门:https://www.luogu.org/problemnew/show/P2278 Solutiton 挺简单的一道模拟题,拿堆模拟一下题目意思就好 堆中有两个关键字,分别是优先级和 ...

  6. Spring 自调用事务失效,你是怎么解决的?

    前言 相信大家都遇到一种事务失效场景,那就是 Spring 自调用,就是在 Service 方法内,调用另一个加 @Transactional 注解的方法,发现事务失效,这时候你是怎么解决的呢? 公众 ...

  7. 什么是4G模块 4G模块的工作原理及特点

    什么是4G模块 4G模块,也被叫做4G通信模块或4G DTU模块,他是物联网行业具有4G通信功能的一种产品,通过4G模块,我们可以实现工业设备数据通过无线4G网络传输到远端控制中心,并从控制中心通过4 ...

  8. leetcode143zigzag-conversion

    题目描述 字符串"PAYPALISHIRING"写成3行的Z字形的样式如下: P A H N↵A P L S I I G↵Y I R 按行读这个Z字形图案应该是 "PAH ...

  9. UDP局域网通信的Java实现及Android平台尝试

    局域网通信已经很少被他人所提及了,我曾经还尝试过通过蓝牙构建通信网络,这次有机会尝试UDP局域网通信,在这里把一些基本过程和在Android平台上的问题记录一下. 1. UDP基础知识 1.1 什么是 ...

  10. mybatis 字符串比较 == 用法

    private String deptLevel; <when test='deptLevel=="3"'> 正确 <when test="deptLe ...