银行家算法

文章目录

主要内容

一.银行家算法

1.需求分析

通过编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生条件,采用适当的算法,有效防止和避免死锁发生。

  1. 模拟一个银行家算法,判断是否处于安全状态。
  2. 初始化时,让系统拥有一定的资源。
  3. 如果预分配后,系统处于不安全状态,则提示不能满足请求。

1.设置数据结构:包括资源向量(Resource),最大需求矩阵(Need),分配矩阵(Allocation),需求矩阵(Request), 可利用剩余资源数(Available)。
2.设计安全性算法:设置工作向量 Work 表示系统可提供进程继续运行可利用资源数目,Finish 表示系统是否有足够的资源分配给进程。
3. 利用三组数据分别测试银行家算法,并给出结果,包括安全状态和不安全状态。安全状态请给出进程进行资源分配的安全序列。

2.概要设计

为了实现银行家算法,在系统中必须设置这样四个数据结构:
1)Available 向量:系统中可利用的资源数目
2)Max 矩阵:每个进程对每种资源的最大需求
3)Allocation 矩阵:每个进程已分配的各类资源的数目
4)Need 矩阵:每个进程还需要的各类资源数,其中三个矩阵间存在下述关系:
Need[i,j] = Max[i,j] - allocation[i, j]

算法逻辑:
设 Requesti 是进程 Pi 的请求向量,如果 Requesti[j]=K,表示进程 Pi 需要 K 个 Rj 类型的
资源。当 Pi 发出资源请求后,系统按下述步骤进行检查:
(1) 若 Requesti[j] ≤ Need[i,j],转向(2),否则认为出错(因为它所需的资源数目已超过它所宣布的最大值)。
(2) 若 Requesti[j] ≤ Available[j],转向(3),否则须等待(表现为进程 Pi 受阻)。
(3) 系统尝试把资源分配给进程 Pi,并修改下面数据结构中的数值:
Available[j] = Available[j]-Requesti[j]
Allocation[i,j] = Allocation[i,j] + Requesti[j]
Need[i,j] = Need[i,j]-Requesti[j]
(4)试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试分配作废,进程 Pi 等待

3.源代码

代码如下(示例):
 #include<stdio.h>
#define true 1
#define false 0
#define N 4
#define M 3
#define MAXINT 9999

int resource[M] = { 10,5,7 };
int available[M] = { 0 };
int need[N][M] =
{ 7,5,3,
3,2,2,
9,0,2,
2,2,2 };
int allocation[N][M] =
{ 0,1,0,
2,0,0,
3,0,2,
2,1,1 };
int request[N][M] = { 0 };
bool Finish[N];
int safeSeries[N] = { MAXINT, MAXINT , MAXINT , MAXINT };//用于存放安全序列


void Init();
void showInfo();
bool isSafe();
void SafeInfo(int* work, int i);

void Init()
{
 int i, j;
 //printf("输入进程数量、资源数量\n");
 //scanf("%d %d",&processNum,&resourceNum);

 printf("输入当前资源数目\n");
 for (i = 0; i < M; i++) {
  scanf("%d", &resource[i]);
 }
 printf("输入最大需求矩阵\n");
 for (i = 0; i < N; i++) {
  for (j = 0; j < M; j++) {
   scanf("%d", &need[i][j]);
  }
 }
 printf("输入分配矩阵\n");
 for (i = 0; i < N; i++) {
  for (j = 0; j < M; j++) {
   scanf("%d", &allocation[i][j]);
  }
 }
 // printf("输入当前需求矩阵\n");
 for (i = 0; i < N; i++)
 {
  for (j = 0; j < M; j++)
  {
   request[i][j] = need[i][j] - allocation[i][j];
  }
 }
}

void showInfo()
{
 int i, j;
 printf("当前资源总量:");
 for (j = 0; j < M; j++) {
  printf("%d ", resource[j]);
 }
 printf("\n");
 //计算Avaliable向量
 for (i = 0; i < M; i++)
 {
  int count = 0;
  for (j = 0; j < N; j++)
  {
   count += allocation[j][i];
  }
  available[i] = resource[i] - count;
 }
 //计算request向量
 for (i = 0; i < N; i++)
 {
  for (j = 0; j < M; j++)
  {
   request[i][j] = need[i][j] - allocation[i][j];
  }
 }
 printf(" PID\t Need\t\tAllocation\tRequest\n");
 for (i = 0; i < N; i++)
 {
  printf(" P%d\t", i);
  for (j = 0; j < M; j++)
  {
   printf("%d ", need[i][j]);
  }
  printf("\t\t");
  for (j = 0; j < M; j++)
  {
   printf("%d ", allocation[i][j]);
  }
  printf("\t\t");
  for (j = 0; j < M; j++)
  {
   printf("%d ", request[i][j]);
  }
  printf("\n");
 }
 printf("当前资源剩余:");
 for (j = 0; j < M; j++) {
  printf("%d ", available[j]);
 }
}

bool isSafe()
{
 int i, j, k;
 int trueFinished = 0;
 int work[M];
 for (i = 0; i < M; i++)
 {
  work[i] = available[i];//
 }

 for (i = 0; i < N; i++)
 {
  Finish[i] = false;
 }
 i = 0;
 int temp = 0;
 int temp0 = 0;
 int flag = 0;
 while (trueFinished != N)
 {
  int j = 0;
  if (Finish[i] != true)
  {
   for (j = 0; j < M; j++)
   {
    if (request[i][j] > work[j])
    {
     break;
    }
   }
  }
  if (j == M)
  {
   Finish[i] = true;
   SafeInfo(work, i);
   for (k = 0; k < M; k++)
   {
    work[k] += allocation[i][k];
   }
   int k2;
   safeSeries[trueFinished++] = i;
  }
  i++;
  if (i >= N)
  {
   if (flag == 0)
   {
    temp = trueFinished;
    temp0 = trueFinished;
   }
   i = i % N;
   if (flag == 1) {
    temp = trueFinished;
    if (temp == temp0)
     break;
    else
     temp0 = temp;
   }
   flag = 1;
  }
  temp = trueFinished;
 }

 if (trueFinished == N)
 {
  printf("\n系统安全!\n\n安全序列为:");
  for (i = 0; i < N; i++)
  {
   printf("%d ", safeSeries[i]);
  }
  printf("\n");
  return true;
 }
 printf("******系统不安全!******\n");
 return false;
}

void SafeInfo(int* work, int i)
{
 int j;
 printf(" P%d\t", i);
 for (j = 0; j < M; j++)
 {
  printf("%d ", work[j]);
 }
 printf("\t\t");
 for (j = 0; j < M; j++)
 {
  printf("%d ", request[i][j]);
 }
 printf("\t ");
 for (j = 0; j < M; j++)
 {
  printf("%d ", allocation[i][j]);
 }
 printf("\t\t");
 for (j = 0; j < M; j++)
 {
  printf("%d ", allocation[i][j] + work[j]);
 }
 printf("\n");
}

int main()
{
 int i, j, curProcess;
 int wheInit = 0;
 printf("是否使用内置数据?0是,1否:");
 scanf("%d", &wheInit);
 if (wheInit)
 {
  Init();
 }
 printf("---------------------------------------------------------\n");
 showInfo();
 printf("\n---------------------------------------------------------\n");
 printf("\n系统安全情况分析\n");
 printf(" PID\t Work\t\tRequest\tAllocation\tWork+Allocation\n");
 isSafe();
 return 0;
}

在这里插入图片描述
在这里插入图片描述


总结

以上是今天要讲的内容,练习了银行家算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/331825.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java并发编程: 并发编程中的ExecutionException异常

一、什么是ExecutionException 在并发编程中在执行java.util.concurrent.Future实现类的get方法时&#xff0c;需要捕获java.util.concurrent.ExecutionException这个异常。Future.get()方法通常是要获取任务的执行结果&#xff0c;当执行任务的过程中抛出了异常&#xff0c;就…

WAF攻防相关知识点总结2-代码免杀绕过

WAF的检测除了有对于非正常的流量检测外还对于非正常的数据包特征进行检测 以宝塔为例 在宝塔的后台可以放置一句话木马的文件 宝塔不会对于这个文件进行拦截&#xff0c;但是一旦我们使用菜刀蚁剑等webshell工具去进行连接的时候&#xff0c;数据报中有流量特征就会被拦截 …

【十进制与二进制如何转换?推荐一个超好用的公式编辑器】

在计算机科学和电子工程中&#xff0c;二进制是一种非常重要的数字系统&#xff0c;因为它在数字处理和数据传输中被广泛使用。因此&#xff0c;理解如何将十进制数转换为二进制数是非常重要的。 可以使这个计算过程更加简单和快速。而且还可以用于其他数学方程式的编写和编辑。…

MAC磁盘空间不足怎么清理?MAC清理磁盘空间的五种方法

MAC磁盘空间不足怎么清理&#xff1f;当我们使用苹果MAC一段时间后&#xff0c;就会有大量的垃圾文件占用磁盘空间&#xff0c;例如系统缓存文件、应用程序缓存文件、备份和重复文件、旧版的应用程序及其部件等&#xff0c;为了不影响电脑的后续使用&#xff0c;我们需要经常清…

2. Git

2. Git Git简介 Git是什么&#xff1f; Git是目前世界上最先进的分布式版本控制系统&#xff08;没有之一&#xff09;。 Git有什么特点&#xff1f;简单来说就是&#xff1a;高端大气上档次&#xff01; 那什么是版本控制系统&#xff1f; 如果你用Microsoft Word写过长篇大…

IP定位助力网络安全防线

随着互联网技术的飞速发展&#xff0c;网络安全问题日益凸显。在网络安全领域&#xff0c;IP地址定位技术正发挥着越来越重要的作用&#xff0c;成为维护网络安全的一道有力防线。 一、追踪黑客攻击者&#xff0c;维护公共安全 在网络安全领域&#xff0c;黑客攻击是一个严重的…

RK3568平台开发系列讲解(Linux系统篇)中断下文 tasklet

🚀返回专栏总目录 文章目录 一、什么是 taskle二、tasklet 相关接口函数2.1、静态初始化函数2.2、动态初始化函数2.3、关闭函数2.4、使能函数2.5、调度函数2.6、销毁函数三、测试程序沉淀、分享、成长,让自己和他人都能有所收获!😄

设计模式入门

0. 类图 1. 设计原则 1.单一职责原则&#xff1a;每个类只有一个功能 2.开放封闭原则&#xff1a;模块和函数应该对扩展开放(对提供方)&#xff0c;对修改关闭(对使用方) 3.里氏代换原则&#xff1a;子类拥有父类的所有方法和属性&#xff0c;从而可以减少创建类的工作量 4.依…

输入框输入关键字 下拉框的关键字高亮

直接上代码 //搜索框部分 <div><input v-modelkeyWord /><button clickseachFn>搜索</button> </div> //下拉框部分 <div><div v-html"item.name" v-foritem in droplist :keyitem.id></div> </div> <sc…

洛谷 P2415 集合求和

原文链接&#xff1a;洛谷 P2415 集合求和 一、题目链接 集合求和 - 洛谷 妥妥的一道数学问题&#xff0c;把数学层面的问题解决了&#xff0c;代码很好写&#xff1b; 题意&#xff1a;给n个元素的集合&#xff0c;求出所有子集的元素的和。 二、题目分析 思考一下&…

2024年【建筑电工(建筑特殊工种)】考试报名及建筑电工(建筑特殊工种)免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 建筑电工(建筑特殊工种)考试报名是安全生产模拟考试一点通总题库中生成的一套建筑电工(建筑特殊工种)免费试题&#xff0c;安全生产模拟考试一点通上建筑电工(建筑特殊工种)作业手机同步练习。2024年【建筑电工(建筑特…

189.轮转数组(数组翻转,C解法)

题目描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转…

C++--默认参数

一.默认参数&#x1f357; C中允许函数提供默认参数&#xff0c;也就是允许在函数的声明或定义时给⼀个或多个参数指定默认值。在调 ⽤具有默认参数的函数时&#xff0c;如果没有提供实际参数&#xff0c;C将⾃动把默认参数作为相应参数的值。 二.使用规则&#x1f357; 1.如果…

Java中List接口两个实现,ArrayList类和LinkedList类的常用方法(一)

List接口 要了解List接口&#xff0c;就不得不说起Java的集合框架。 &#xff08;该图来自菜鸟教程&#xff09; Collection接口和Map接口 Java 集合框架主要包括两种类型的容器&#xff0c;集合Collection和图Map。 Collection接口代表了单列集合&#xff0c;它包含了一组…

恭喜所有纺织人,你最想要的小程序来了

随着互联网的普及和电子商务的快速发展&#xff0c;越来越多的商家开始涉足线上销售。而小程序商城作为一种轻量级的应用程序&#xff0c;正逐渐成为商家们热衷选择的销售平台。本文将通过实用指南的形式&#xff0c;为商家们详细介绍如何通过乔拓云网后台&#xff0c;自助搭建…

Mybatis面试题(二)

MyBatis 面试题 11、Mybatis是如何将sql执行结果封装为目标对象并返回的&#xff1f;都有哪些映射形式&#xff1f; 第一种是使用标签&#xff0c;逐一定义数据库列名和对象属性名之间的映射关系。 第二种是使用 sql 列的别名功能&#xff0c;将列的别名书写为对象属性名。 …

.NET架构师:全网最全“权限系统”设计剖析

&#x1f3c6;作者&#xff1a;科技、互联网行业优质创作者 &#x1f3c6;专注领域&#xff1a;.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 &#x1f3c6;欢迎关注我&#xff08;Net数字智慧化基地&#xff09;&#xff0c;里面…

品鉴威士忌:威士忌酿造发酵,糖类到酒精的转变

威士忌&#xff0c;这一源自苏格兰的特别蒸馏酒&#xff0c;以其丰富的味蕾和特别的风味吸引了无数品鉴者。在威士忌的酿造过程中&#xff0c;发酵是从糖类物质转化为酒精的重要环节。本文将带您深入了解威士忌发酵的过程&#xff0c;以及如何捕捉那些难以言喻的美妙味蕾感受。…

Seaborn可视化的各种图及代码演示

一.简介 Seaborn是基于matplotlib的图形可视化python包。它提供了一种高度交互式界面&#xff0c;便于用户能够做出各种有吸引力的统计图表。 Seaborn是在matplotlib的基础上进行了更高级的API封装&#xff0c;从而使得作图更加容易&#xff0c;在大多数情况下使用seaborn能做…

FFmpeg之AVFilter

文章目录 一、概述二、重要结构体2.1、AVFilterGraph2.2、AVFilter2.3、AVFilterContext 三、流程梳理3.1、FFmpeg AVFilter 使用整体流程3.2、过滤器构建流程3.2.1、分配AVFilterGraph3.2.2、创建过滤器源3.2.3、创建接收过滤器3.2.4、生成源和接收过滤器的输入输出3.2.5、通过…