【操作系统】银行家算法实现(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. Codeforces Round #679 (Div. 2, based on Technocup 2021 Elimination Round 1)

    考场上只做出来四道,第二天一早就写出来了E,蛮绝望的. A Finding Sasuke 水构造 #include <cstdio> #include <algorithm> ...

  2. 对Python"一切皆对象"的小参悟

    写在前面 若有误区请大神不吝指正,以免带偏了如我者的弱鸡们 据闻对此不再懵逼后,于函数以及高阶函数编程的进阶有益 类:又称对象,由类创建的个体被称为实例 名言名句"一切皆对象(一切皆类,一切 ...

  3. 傲视Kubernetes(一):Kubernetes简介

    前言 从上个月,因工作需要外加兴趣所知,博主开始学习Kubernetes,时至今日可以说是刚刚入门.独自学不如一起学,后面博主会一边学着一边将学习内容以博文的形式呈现出来,希望能跟各位园友有问题一起讨 ...

  4. HTTPDNS开源 Android SDK,赋能更多开发者参与共建

    为赋能更多开发者参与共建,阿里云HTTPDNS开源 Android SDK,iOS SDK也在做开源准备,不久也将开放给开发者.HTTPDNS是阿里云移动研发平台面向多端应用(移动端APP,PC客户端 ...

  5. 【笔记】拉勾Java工程师高薪训练营-第一阶段 开源框架源码解析-模块一 持久层框架涉及实现及MyBatis源码分析-任务一:自定义持久层框架

    以下笔记是我看完视频之后总结整理的,部分较为基础的知识点也做了补充,如有问题欢迎沟通. 目录 任务一:自定义持久层框架 1.1 JDBC回顾及问题分析 1.2 自定义持久层框架思路分析 1.3 IPe ...

  6. 09线程隔离的g对象

    1,g是global的意思. g对象再一次请求中的所有的代码的地方,都是可以使用的. 同一次请求,那么在这个项目的所有地方都可以用了. from flask import Flask,request, ...

  7. 判断机器是big-endian、little-endian

    联合体union和大小端(big-endian.little-endian):下边示范了一种用途,代表四个含义的四个变量,但是可以用一个int来操作,直接int赋值,无论内存访问(指针大小的整数倍,访 ...

  8. C++调用Go方法的字符串传递问题及解决方案

    摘要:C++调用Go方法时,字符串参数的内存管理需要由Go侧进行深度值拷贝. 现象 在一个APP技术项目中,子进程按请求加载Go的ServiceModule,将需要拉起的ServiceModule信息 ...

  9. Android自定控件基础(一)——几何图形绘制

    虽然本人有几年开发经验,但是自定义控件这一块儿,研究的很少,惭愧--用到的时候就是百度查找,复制粘贴.工时紧,总是想的快点完工就好.(都是借口啦,想学总会有时间哒) 作为一个Android开发 要说自 ...

  10. ubuntu安装软件自动交互

    在ubuntu下安装软件过程中可能会出现需要你输入密码或者其他的一些交互类的操作,这样在脚本安装的时候就可能出现阻断,这个在ubuntu里面已经考虑到了这个情况,以前我在安装这个的时候,通过的是脚本传 ...