操作系统实验之银行算法

一、实验目的

        采用高级语言编写一个动态分配系统资源的程序,模拟死锁现象,观察死锁发生的条件,并采用适当的算法,有效地防止死锁的发生。

二、实验内容

        本次实验采用银行算法防止死锁的发生。设有3个并发进程共享10个系统资源。在3个进程申请系统资源之和不超过10时,当然不可能发生死锁,因为各个进程资源都能满足。在有一个进程申请的系统资源数超过10时,必然会发生死锁。应该排队这两种情况。程序采用人工输入各进程的申请资源序列。如果随机给各进程分配资源,就可能发生死锁,这也就是不采用防止死锁算法的情况。假如,按照一定的规则,为各进程分配资源,就可以防止死锁的发生。

三、实验步骤

3.1任务分析

3.1.1 实验任务

  1. 设计一个几个并发进程共享m个系统资源的系统。进程可动态的申请资源和释放资源,系统按各进程的申请动态的分配资源。
  2. 系统应能显示各进程申请和释放资源的过程,能显示系统动态分配资源的过程,便于观察和分析。
  3. 系统应能选择是否采用防止死锁的算法,应设计多种防止死锁的算法,并能任意选择其中任何一种投入运行,同时要求,在不采用防止死锁算法时观察死锁现象发生的过程,在使用防止死锁的算法时,了解在同样条件下防止死锁发生的过程。

3.2 概要设计

抽象数据类型的定义:

1)资源:

属性:名称(name)、数量(amount)

操作:

初始化资源(InitResource(name, amount))

获取资源名称(GetName())

获取资源数量(GetAmount())

设置资源数量(SetAmount(amount))

2)进程:

属性:进程编号(ID)、最大需求资源(Max)、已分配资源(Allocation)、还需资源(Need)

操作:

初始化进程(InitProcess(ID, Max, Allocation))

获取进程编号(GetID())

获取最大需求资源矩阵(GetMax())

获取已分配资源矩阵(GetAllocation())

获取还需资源矩阵(GetNeed())

3)系统状态:

属性:可用资源(Available)、进程集合(Processes)

操作:

初始化系统状态(InitSystemState(Available, Processes))

获取可用资源矩阵(GetAvailable())

获取进程集合(GetProcesses())

c3837dac7de2429e9db14ed2c0e5dc94.png

主程序流程:

  1. 初始化系统状态:

输入资源种类数量和初始资源量、进程数量、每个进程的最大资源需求、已分配给每个进程的资源

  1. 显示初始系统状态:

调用显示系统状态函数(ShowSystemState())

  1. 安全性检查:

调用安全性算法函数(CheckSafety())

  1. 功能选择循环:

进入功能选择循环,直到用户选择离开。用户可以选择增加资源、删除资源、修改资源、分配资源、增加作业等功能

 

程序模块调用关系:

主程序根据用户选择调用相应的功能函数

  1. 增加资源:调用增加资源函数(AddResource())
  2. 删除资源:调用删除资源函数(DeleteResource())
  3. 修改资源:调用修改资源函数(ModifyResource())
  4. 分配资源:调用分配资源函数(AllocateResource())
  5. 增加作业:调用增加作业函数(AddJob())

c604fef8707048749d27a9f78b26e2c1.png 

3.3详细设计 

银行算法:顾名思义是来源于银行的借贷业务,一定数量的本金要应付各种客户的借贷周转,为了防止银行因资金无法周转而倒闭,对每一笔贷款,必须考察其最后是否能归还。研究死锁现象时就碰到类似的问题,有限资源为多个进程共享,分配不好就会发生每个进程都无法继续下去的死锁僵局。

银行算法的原理是先假定某一次分配成立,然后检查由于这次分配是否会引起死锁,即剩下的资源是不是能满足任一进程完成的需要。如这次分配是安全的(不会引起死锁),就实施本次分配,再作另一种分配试探,一直探索到各进程均满足各自的资源请求,防止了死锁的发生。

主要函数设计:

main() 函数作为程序的入口,首先提示用户输入系统资源种类和数量,并进行初始化。用户需要输入作业数量和每个进程的最大需求量,以及每个进程已经申请的资源量。程序提供了一个菜单,让用户选择不同的功能,如增加资源、删除资源、修改资源、分配资源、增加作业等。

de02aa4f350e4671881584b270e3bc25.png

showdata函数用于展示当前系统的资源分配状况,包括每个进程的最大需求、已分配资源和尚需资源。

changdata函数用于变更资源分配情况,主要在资源请求得到批准后调用。

 603c6e9d45184937ba9f56eaa477e55a.png

safe函数实现了银行家算法的核心,即安全性算法。这个函数检查在当前资源分配情况下,系统是否处于安全状态。使得每个进程都可以按需求获得资源,执行完毕后释放资源,从而避免死锁。 

42b79a9142e8428b824b6aebd4e3a964.png 

share函数处理资源请求,首先检查请求是否合理(即请求量不超过需求量和可用量),然后尝试分配资源,并调用safe函数检查系统是否仍然安全。

addresources、delresources、changeresources和addprocess函数提供了添加、删除、修改资源和添加作业的功能,以适应动态变化的资源需求。

f7ce4da09b78460981d0def28f8ca4fd.png

3.4调试分析

改进设想:

  1. 引入异常处理机制,处理用户输入错误、系统状态异常等情况,提高程序的健壮性。
  2. 在用户输入时进行更严格的检查,防止非法输入导致程序崩溃或不稳定。

 3.5测试结果

4c0574e81a844859ae27d2e37e33432f.png

40c5daa88ec7401c96cced4311c2f49c.png

63a0758479744878be91ba276635263b.png

28b660eabd234b75919b70557c8effa0.png

bc924bfe31dd4009abb8c4cd95695ec6.png

cb62856c7f2c425c93056d7fa1f684ab.png

eb2fecb20eb1433f9645d5e46870bf3e.png

测试结果和预期相同

3.6使用说明

运行程序,输入系统可供资源种类数量,名称,资源数量

b9f9b124328a4275b1e1af9d84dd1fa2.png

输入作业数量,各进程最大需求量,已申请的资源量

0a411935c00441369cb7cbf8d6f6127b.png

输出系统目前可用资源,以及各进程资源分配

9be266bc30cc42768ce49298bcf0c4ed.png

根据需求选择功能

ad6dda2fd8ab4a5e971b66915e28a2f2.png

四、实验总结

        通过本次实验,我学习了。在实践中,我通过代码实现和调试更深刻地理解了银行家算法的工作原理和优缺点,也更直观的了解死锁发生的原因,初步掌握防止死锁、解除死锁的简单方法,加深理解教材中有关死锁的内容。

       银行家算法是用于避免死锁的一种资源分配算法,它根据系统的状态和进程的资源需求来判断是否能够安全地分配资源。其可以有效地避免了死锁情况的发生,通过检查资源分配的请求,只有在分配资源不会导致系统不安全状态时才进行分配。并且确保只有在系统能够提供足够资源的情况下,才会分配资源给进程,保证资源的合理利用。但是由于算法会保留一部分资源以应对未来可能的请求,因此可能导致资源的浪费。除此之外,在每次资源请求时进行安全性检查,这可能会引入一定的开销。

        这次实验不仅让我更加熟悉操作系统的内部机制,也为我今后深入学习操作系统和计算机体系结构提供了基础。也意识到操作系统的设计和优化是一个复杂而细致的工作,需要综合考虑各种因素,权衡不同的算法和策略。

五、附录

#include <stdio.h>
#include <string.h>
#define False 0
#define True 1
#define MAX 100int Max[MAX][MAX] = {0};          // 各进程所需各类资源的最大需求
int Avaliable[MAX] = {0};         // 系统可用资源
char name[MAX] = {0};             // 资源的名称
int Allocation[MAX][MAX] = {0};   // 系统已分配资源
int Need[MAX][MAX] = {0};         // 还需要资源
int Request[MAX] = {0};           // 请求资源向量
int temp[MAX] = {0};              // 存放安全序列
int Work[MAX] = {0};              // 存放系统可提供资源
int M = 100;                      // 作业的最大数为100
int N = 100;                      // 资源的最大数为100void showdata();                  // 显示资源矩阵
int changdata(int i);             // 进行资源分配
int safe();                       // 安全性算法
void share();                     // 利用银行家算法对申请资源对进行判定
void addresources();              // 添加资源
void delresources();              // 删除资源
void changeresources();           // 修改资源
void addprocess();                // 添加作业int main() {int i, j, number, choice, m, n, flag;char ming;// 输入系统可供资源种类数量和初始资源量printf("***********************************\n");printf("系统可供资源种类数量:");scanf("%d", &n);N = n;for (i = 0; i < n; i++) {printf("资源%d名称:", i + 1);scanf(" %c", &ming);name[i] = ming;printf("资源数量:");scanf("%d", &number);Avaliable[i] = number;}// 输入进程数量printf("作业数量:");scanf("%d", &m);M = m;// 输入每个进程的最大资源需求printf("各进程的最大需求量(%d*%d矩阵)[Max]:\n", m, n);for (i = 0; i < m; i++) {for (j = 0; j < n; j++) {scanf("%d", &Max[i][j]);Need[i][j] = Max[i][j];}}// 输入已分配给每个进程的资源,并验证输入的合法性do {flag = 0;printf("各进程已经申请的资源量(%d*%d矩阵)[Avaliable]:\n", m, n);for (i = 0; i < m; i++) {for (j = 0; j < n; j++) {scanf("%d", &Allocation[i][j]);if (Allocation[i][j] > Max[i][j]) {flag = 1;}Need[i][j] = Max[i][j] - Allocation[i][j];}}if (flag) {printf("申请的资源大于最大需求量,请重新输入!\n");}} while (flag);showdata();safe();choice = 1;// 菜单驱动循环,提供不同的功能选项while (choice) {printf("\n");printf("1:增加资源    \n");printf("2:删除资源    \n");printf("3:修改资源    \n");printf("4:分配资源    \n");printf("5:增加作业    \n");printf("0:离开        \n");printf("*\n");printf("请选择功能:");scanf("%d", &choice);switch (choice) {case 1:addresources();break;case 2:delresources();break;case 3:changeresources();break;case 4:share();break;case 5:addprocess();break;case 0:choice = 0;break;default:printf("请正确选择功能(0-5)\n");break;}}return 1;
}// 显示当前资源和进程状态的函数
void showdata() {int i, j;printf("系统目前可用的资源[Avaliable]:\n");for (i = 0; i < N; i++) {printf("%c ", name[i]);}printf("\n");for (j = 0; j < N; j++) {printf("%d ", Avaliable[j]);}printf("\n");printf("      Max  Allocation  Need\n");printf("进程名  ");for (j = 0; j < 3; j++) {for (i = 0; i < N; i++) {printf("%c ", name[i]);}printf("      ");}printf("\n");for (i = 0; i < M; i++) {printf(" %d     ", i);for (j = 0; j < N; j++) {printf("%d ", Max[i][j]);}printf("      ");for (j = 0; j < N; j++) {printf("%d ", Allocation[i][j]);}printf("      ");for (j = 0; j < N; j++) {printf(" %d ", Need[i][j]);}printf("\n");}
}// 当资源分配给进程时更新资源分配和需求的函数
int changdata(int i) {int j;for (j = 0; j < M; j++) {Avaliable[j] = Avaliable[j] - Request[j];Allocation[i][j] = Allocation[i][j] + Request[j];Need[i][j] = Need[i][j] - Request[j];}return 1;
}// 使用银行家算法检查系统是否处于安全状态的函数
int safe() {int i, k = 0, m, apply, Finish[MAX] = {0};int j;int flag = 0;// 使用可用资源初始化Work数组Work[0] = Avaliable[0];Work[1] = Avaliable[1];Work[2] = Avaliable[2];// 检查进程是否能够完成而不会导致死锁for (i = 0; i < M; i++) {apply = 0;for (j = 0; j < N; j++) {if (Finish[i] == False && Need[i][j] <= Work[j]) {apply++;if (apply == N) {for (m = 0; m < N; m++) {Work[m] = Work[m] + Allocation[i][m];}Finish[i] = True;temp[k] = i;i = -1;k++;flag++;}}}}for (i = 0; i < M; i++) {if (Finish[i] == False) {printf("系统不安全\n");return -1;}}printf("系统是安全的\n");printf("分配的序列:");for (i = 0; i < M; i++) {printf("%d", temp[i]);if (i < M - 1) {printf("->");}}printf("\n");return 0;
}// 分配资源的函数
void share() {char ch;int i = 0, j = 0;ch = 'y';printf("请输入要求分配的资源进程号(0-%d):", M - 1);scanf("%d", &i);printf("请输入进程 %d 申请的资源:\n", i);for (j = 0; j < N; j++) {printf("%c:", name[j]);scanf("%d", &Request[j]);}for (j = 0; j < N; j++) {if (Request[j] > Need[i][j]) {printf("进程 %d 申请的资源大于它需要的资源 分配不合理,不予分配!\n", i);ch = 'n';break;} else {if (Request[j] > Avaliable[j]) {printf("进程 %d 申请的资源大于系统现在可利用的资源 分配出错,不予分配!\n", i);ch = 'n';break;}}}if (ch == 'y') {changdata(i);showdata();safe();}
}// 添加资源的函数
void addresources() {int n, flag;printf("请输入需要添加资源种类的数量:");scanf("%d", &n);flag = N;N = N + n;for (int i = 0; i < n; i++) {printf("名称:");scanf(" %c", &name[flag]);printf("数量:");scanf("%d", &Avaliable[flag++]);}showdata();safe();
}// 删除资源的函数
void delresources() {char ming;int i, flag = 1;printf("请输入需要删除的资源名称:");do {scanf(" %c", &ming);for (i = 0; i < N; i++) {if (ming == name[i]) {flag = 0;break;}}if (i == N) {printf("该资源名称不存在,请重新输入:");}} while (flag);for (int j = i; j < N - 1; j++) {name[j] = name[j + 1];Avaliable[j] = Avaliable[j + 1];}N = N - 1;showdata();safe();
}// 修改资源的函数
void changeresources() {printf("系统目前可用的资源[Avaliable]:\n");for (int i = 0; i < N; i++) {printf("%c:%d\n", name[i], Avaliable[i]);}printf("输入系统可用资源[Avaliable]:\n");for (int k = 0; k < N; k++) {printf("%c:", name[k]);scanf("%d", &Avaliable[k]);}printf("经修改后的系统可用资源为\n");for (int k = 0; k < N; k++) {printf("%c:%d\n", name[k], Avaliable[k]);}showdata();safe();
}// 添加作业的函数
void addprocess() {int flag = M;M = M + 1;printf("请输入该作业的最大需求量[Max]\n");for (int i = 0; i < N; i++) {printf("%c:", name[i]);scanf("%d", &Max[flag][i]);Need[flag][i] = Max[flag][i] - Allocation[flag][i];}showdata();safe();
}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

AQS机制详解

案例一 public class AqsThread extends Thread {private Lock lock;public AqsThread(String name, Lock lock) {super(name);this.lock lock;}Overridepublic void run() {lock.lock();try {System.out.println(Thread.currentThread().getName() "running");} …

【LeetCode】每日一题 2024_10_5 完成旅途的最少时间(二分答案)

前言 每天和你一起刷 LeetCode 每日一题~ 大家国庆节快乐呀~ LeetCode 启动&#xff01; 突然发现&#xff0c;国庆的每日一题&#xff0c;不是坐公交就是坐火车&#xff0c;不是坐火车就是做飞机&#xff0c;这就是你的国庆旅游计划吗&#xff01;力扣&#xff01; 题目&a…

图表不会做怎么办?AI一键生成好看图表!

本期教你如何用AI一键生成各种数据图表&#xff01; 本文阅读难度&#xff1a;★☆☆☆☆ 看看别人做的这些图表&#xff0c;是不是挺好看的&#xff1f; 特别是作为接商单的新写手&#xff0c;看到这些&#xff0c;头都大了&#xff0c;该怎么办呢&#xff1f; 不用怕&…

ModuleNotFoundError: No module named ‘package‘

报错&#xff1a; Traceback (most recent call last): File “”, line 198, in run_module_as_main File “”, line 88, in run_code File "D:\python\helloworld.venv\Scripts\pip.exe_main.py", line 4, in File "D:\python\helloworld.venv\Lib\site-pac…

MAC备忘录空白解决方案

打开icloud->备忘录 取消勾选同步此MAC后再次勾选&#xff0c;然后点击完成即可。

S7-200 SMART的数据类型说明

S7-200 SMART的数据主要分为&#xff1a; 与实际输入/输出信号相关的输入/输出映象区&#xff1a; I&#xff1a;数字量输入&#xff08;DI&#xff09;Q&#xff1a;数字量输出&#xff08;DO&#xff09;AI&#xff1a;模拟量输入AQ&#xff1a;模拟量输出 内部数据存储区…

NVIDIA网卡系列之ConnectX-4规格信息(50G-PCIe 3.0x8-8PF256VF-2015年发布)

背景 NVIDIA ConnectX-4系列的网卡&#xff0c;早期还在Mellanox未被NVIDIA收购的时候就发布了&#xff0c;支持50G&#xff0c;PCIe3.0&#xff0c;最大x8通道lanes。 是50G级别的一代&#xff08;10G-CX3&#xff0c;50G-CX4&#xff0c;100G-CX5&#xff0c;200G-CX6&#…

基于Python的自然语言处理系列(24):BiDAF(双向注意力流)

在自然语言处理领域,机器阅读理解(Machine Comprehension, MC)是一个重要的任务。在这篇博文中,我们将实现论文 BiDAF 中提出的双向注意力流模型。BiDAF 主要改进了传统注意力机制中的早期信息摘要问题,并引入了字符嵌入来加强对单词细粒度信息的理解。 1. 加载 SQuAD 数据…

ThreadLocal底层原理及数据结构详解

ThreadLocal允许为每个线程创建独立的变量副本&#xff0c;使得同一个ThreadLocal对象在不同的线程中拥有不同的值。它的主要作用是在并发环境下提供线程隔离&#xff0c;避免多个线程共享同一个变量&#xff0c;从而减少线程间的相互干扰。 ThreadLocal的核心在于为每个线程维…

【案例】距离限制模型透明

开发平台&#xff1a;Unity 2023 开发工具&#xff1a;Unity ShaderGraph   一、效果展示 二、路线图 三、案例分析 核心思路&#xff1a;计算算式&#xff1a;透明值 实际距离 / 最大距离 &#xff08;实际距离 ≤ 最大距离&#xff09;   3.1 说明 | 改变 Alpha 值 在 …

【JAVA开源】基于Vue和SpringBoot的服装生产管理系统

本文项目编号 T 066 &#xff0c;文末自助获取源码 \color{red}{T066&#xff0c;文末自助获取源码} T066&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

git diff 查看到一行变动,但是目测无差异怎么办?

1. 目测无变化 直接用 git diff main.js 提示有一行变动&#xff0c;但是目测看不出来差异。 结果如图&#xff1a;up panel. 2. 大概是空格的问题&#xff0c;使用参数 --ws-error-highlightall $ git diff --ws-error-highlightall main.js结果如图: down panel.

黑神话:仙童,数据库自动反射魔法棒

黑神话&#xff1a;仙童&#xff0c;数据库自动反射魔法棒 Golang 通用代码生成器仙童发布了最新版本电音仙女尝鲜版十一及其介绍视频&#xff0c;视频请见&#xff1a;https://www.bilibili.com/video/BV1ET4wecEBk/ 此视频介绍了使用最新版的仙童代码生成器&#xff0c;将 …

Llama 3.2 微调指南

让我们通过微调 Llama 3.2 来找到一些精神上的平静。 我们需要安装 unsloth&#xff0c;以更小的尺寸实现 2 倍的快速训练 !pip install unsloth!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] githttps://github.co…

Spring Boot技术在大学生就业服务中的应用

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

视频格式批量转换:一键操作,轻松搞定

在处理大量视频文件时&#xff0c;格式转换是一个常见需求&#xff0c;不同的平台和设备对视频格式的要求各不相同&#xff0c;批量转换视频格式能显著提高工作效率。帮助大家轻松应对各种视频格式转换难题。 1.在“视频剪辑高手”的功能选项里切换到“批量转换视频”版块上 2.…

大学生就业服务:Spring Boot技术实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

C++结构体定义和创建

// // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std;int main() {//结构体的定义 struct 结构体名字 { 结构体成员名字 }struct Book{string name;double price;int value;}java; //java是创建的结构体//创建结构体//这是第一种方式Boo…

一篇文章吃透OA系统

一、OA系统是什么&#xff0c;都有什么功能&#xff1f; OA系统&#xff08;Office Automation System&#xff09;是办公自动化系统的简称&#xff0c;是一种利用计算机技术和网络通信技术&#xff0c;为企业和组织提供办公管理和协作支持的信息化系统。OA系统旨在提高办公效…