操作系统实验 C++实现死锁检测算法
实验目的
模拟实现死锁检测算法
实验内容
1、 输入:
“资源分配表”文件,每一行包含资源编号、进程编号两项(均用整数表示,并用空格分隔开),记录资源分配给了哪个进程。
“进程等待表”文件,每一行包含进程编号、资源编号两项(均用整数表示,并用空格分隔开),记录进程正在等待哪个资源。
下面是一个示例:
资源分配表:
1 1
2 2
3 3
进程等待表:
1 2
2 3
3 1
2. 处理:
程序运行时,首先提示“请输入资源分配表文件的文件名:”,再提示“请输入进程等待表文件的文件名:”。 输入两个文件名后,程序将读入两个文件中的有关数据,并按照死锁检测算法进行检测。
3. 输出:
第一行输出检测结果:有死锁或无死锁。
第二行输出进程循环等待队列,即进程编号(如果有死锁)。
4. 文件名约定
源程序名:resourceXXX.cpp或resourceXXX.c(依据所用语言确定)。
输入文件名:由用户自行指定。
结果输出文件名:resultXXX.txt
其中:XXX为学号。
5. 死锁检测算法概述:
当任一进程Pj申请一个已被其他进程占用的资源ri时,进行死锁检测。检测算法通过反复查找进程等待表和资源分配表, 来确定进程Pj对资源ri的请求是否导致形成环路,若是,便确定出现死锁。
6. 测试说明:将事先准备好的一组文件(格式为*.txt),从中为每个程序随机指定一至三个作为输入文件 (被测试者需从键盘输入指定文件的文件名),并查看程序输出结果。
实验代码
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <direct.h> using namespace std;#define MAX_PATH 20const int MAXQUEUE = 100; // 定义表的最大行数typedef struct node {int resource;int process;
} cell;cell occupy[MAXQUEUE];
int occupy_quantity;
cell wait[MAXQUEUE];
int wait_quantity;// 初始化函数
void initial() {int i;for (i = 0; i < MAXQUEUE; i++) {occupy[i].process = -1;occupy[i].resource = -1;wait[i].process = -1;wait[i].resource = -1;}occupy_quantity = 0;wait_quantity = 0;
}// 读数据文件
int readData() {char currentDir[MAX_PATH];_getcwd(currentDir, MAX_PATH);FILE *fp;char fname[20];int i;cout << "请输入资源分配表文件的文件名:" << endl;cin >> fname;if ((fp = fopen(fname, "r")) == NULL) {cout << "错误,文件打不开,请检查文件名:)" << endl;return 0;} else {while (!feof(fp)) {fscanf(fp, "%d %d", &occupy[occupy_quantity].resource, &occupy[occupy_quantity].process);occupy_quantity++;}fclose(fp);}cout << "请输入进程等待表文件的文件名:" << endl;cin >> fname;if ((fp = fopen(fname, "r")) == NULL) {cout << "错误,文件打不开,请检查文件名:)" << endl;return 0;} else {while (!feof(fp)) {fscanf(fp, "%d %d", &wait[wait_quantity].process, &wait[wait_quantity].resource);wait_quantity++;}fclose(fp);}// 输出所读入的数据cout << endl << endl << "输出所读入的数据" << endl;cout << "━━━━━━━━━━━━━━━━━━━━━━━" << endl;cout << "资源分配表" << endl;cout << "资源编号 进程编号" << endl;for (i = 0; i < occupy_quantity; i++) {cout << " " << occupy[i].resource << " " << occupy[i].process << endl;}cout << "───────────────────────" << endl;cout << "进程等待表" << endl;cout << "进程编号 资源编号" << endl;for (i = 0; i < wait_quantity; i++) {cout << " " << wait[i].resource << " " << wait[i].process << endl;}return 1;
}// 检测
void check() {int table[MAXQUEUE][MAXQUEUE];int table1[MAXQUEUE][MAXQUEUE];int i, j, k;int flag, t, p;int max_process;// 初始化表格for (i = 0; i < MAXQUEUE; i++) {for (j = 0; j < MAXQUEUE; j++) {table[i][j] = 0;table1[i][j] = 0;}}// 先找到进程最大编号max_process = -1;for (i = 0; i < occupy_quantity; i++) {if (occupy[i].process > max_process) {max_process = occupy[i].process;}}for (i = 0; i < wait_quantity; i++) {if (wait[i].process > max_process) {max_process = wait[i].process;}}for (i = 0; i < wait_quantity; i++) {for (j = 0; j < occupy_quantity; j++) {if (wait[i].resource == occupy[j].resource) {table[wait[i].process][occupy[j].process] = 1;table1[wait[i].process][occupy[j].process] = 1;}}}cout << "初始等待占用表:" << endl;for (i = 0; i < max_process + 1; i++) {for (j = 0; j < max_process + 1; j++) {cout << table[i][j] << " ";}cout << endl;}cout << endl;for (i = 0; i < max_process + 1; i++) {for (j = 0; j < max_process + 1; j++) {for (k = 0; k < max_process + 1; k++) {table[i][j] = table[i][j] || (table[i][k] && table[k][j]);}}}cout << "检测后的等待占用表:" << endl;for (i = 0; i < max_process + 1; i++) {for (j = 0; j < max_process + 1; j++) {cout << table[i][j] << " ";}cout << endl;}flag = -1;for (i = 0; i < max_process + 1; i++) {if (table[i][i] == 1) {flag = i;break;}}cout << endl << endl << "检测结果" << endl;cout << "───────────────────" << endl;if (flag!= -1) {cout << "存在死锁" << endl;cout << "进程循环等待队列:";p = flag; // 存在进程循环等待队列的那一进程// 进程循环等待队列中的所有进程是 table 表中的这一行是 1 的进程,只是顺序要再确定t = 1;while (t) {cout << p << " ";for (j = 0; j < max_process + 1; j++) {if (table1[p][j] == 1) {if (table[j][flag] == 1) {p = j;break;}}}if (p == flag) t = 0;}cout << flag << endl;} else {cout << "不存在死锁" << endl;}
}// 显示版权信息函数
void version() {cout << endl << endl;cout << " ┏━━━━━━━━━━━━━━━━━━━━━━━┓" << endl;cout << " ┃ 死 锁 检 测 算 法 ┃" << endl;cout << " ┠───────────────────────┨" << endl;cout << " ┃ (c)All Right Reserved Neo ┃" << endl;cout << " ┃ sony006@163.com ┃" << endl;cout << " ┃ version 2004 build 1122 ┃" << endl;cout << " ┗━━━━━━━━━━━━━━━━━━━━━━━┛" << endl;cout << endl << endl;
}int main() {int flag;version();initial();flag = readData();if (flag) check();return 0;
}
实验结果
相关文章:

操作系统实验 C++实现死锁检测算法
实验目的 模拟实现死锁检测算法 实验内容 1、 输入: “资源分配表”文件,每一行包含资源编号、进程编号两项(均用整数表示,并用空格分隔开),记录资源分配给了哪个进程。 “进程等待表”文件&…...

小鹏汽车智慧材料数据库系统项目总成数据同步
1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构: 这几个表总数为100多万,经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图: 界面: SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…...

1、HCIP之RSTP协议与STP相关安全配置
目录 RSTP—快速生成树协议 STP STP的缺点: STP的选举(Listening状态中): RSTP P/A(提议/同意)机制 同步机制: 边缘端口的配置: RSTP的端口角色划分: ensp模拟…...
Linux云服务器docker使用教程
诸神缄默不语-个人CSDN博文目录 我用的是腾讯云服务器,操作系统是OpenCloudOS 9,基本上可以当特色版CentOS用。 docker安装跟各个系统关系太大了,我就不写了。OpenCloudOS 9安装docker见这篇博文:腾讯云服务器使用教程 文章目录 …...
如何从android的webview 取得页面上的数据
要从Android的WebView中获取页面上的数据,通常有几种常见的方法: JavaScript Interface:通过JavaScript和Android Interface进行通信。这种方法允许你在JavaScript中调用Android的方法,反之亦然。 Evaluate JavaScriptÿ…...

VTK知识学习(12)- 读取PNG图像
1、代码 private void ShowPngImage(){vtkPNGReader pngReader vtkPNGReader.New();pngReader.SetFileName("D:\\图像\\boxes\\cardboard_boxes_01.png");pngReader.Update();vtkImageActor imageActor vtkImageActor.New();imageActor.SetInputData(pngReader.Get…...

Springboot项目搭建(3)-更改用户信息与文件上传
1.概要 前一章节完成了用户信息的注册、登录、详细信息查询,以及线程池与拦截器技术。 这一章完善了用户信息更新/更改功能,包括昵称、邮箱、头像、密码等... 而后接触到了本地上传和云上传,其二者区别: 选择本地上传还是云上…...

Docker1:认识docker、在Linux中安装docker
欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…...

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析
目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …...
android 如何获取当前 Activity 的类名和包名
其一:getClass().getSimpleName() public static String getTopActivity(Context context){ ActivityManager am (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); ComponentName cn am.getRunningTasks(1).get(0).topAct…...
Spring Boot 项目 myblog 整理
myblog 项目是一个典型的 Spring Boot 项目,主要包括用户注册、登录、文章管理(创建、查询、更新、删除)等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包: Spring Boot W…...

uniapp 城市选择插件
uniapp城市选择插件 如上图 地址 完整demo <template><view><city-selectcityClick"cityClick":formatName"formatName":activeCity"activeCity":hotCity"hotCity":obtainCitys"obtainCitys":isSearch&quo…...

测试工程师如何在面试中脱颖而出
目录 1.平时工作中是怎么去测的? 2.B/S架构和C/S架构区别 3.B/S架构的系统从哪些点去测? 4.你为什么能够做测试这一行?(根据个人情况分析理解) 5.你认为测试的目的是什么? 6.软件测试的流程ÿ…...

Mesh路由组网
Mesh无线网格网络,多跳(multi-hop)网络,为解决全屋覆盖信号,一般用于家庭网络和小型企业 原理 网关路由器(主路由,连接光猫),Mesh路由器(子路由,…...
LeetCode131:分割回文串
题目链接:131. 分割回文串 - 力扣(LeetCode) 代码如下: class Solution { private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int s…...
详细解析 devmem 命令:在 Linux 系统中直接访问内存的利器
目录 什么是 devmem?为什么需要 devmem?devmem 命令的基本语法devmem 在硬件调试中的应用安全性与风险devmem 的常见应用示例结论 在嵌入式系统开发和硬件调试中,开发者经常需要直接与硬件打交道,访问和修改内存中某些特定区域的内…...

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法
本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时,突然发现它的一个接口,被另一个服务ip频繁的请求。 按理说,之前设置的是,每隔1分钟请求一次接口。但从日志来看,则是1秒钟请求一次ÿ…...
【前端知识】nodejs项目配置package.json深入解读
package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件,它位于项目的根目录下,并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...

XGBOOST算法Python实现(保姆级)
摘要 XGBoost算法(eXtreme Gradient Boosting)在目前的Kaggle、数学建模和大数据应用等竞赛中非常流行。本文将会从XGBOOST算法原理、Python实现、敏感性分析和实际应用进行详细说明。 目录 0 绪论 一、材料准备 二、算法原理 三、算法Python实现 3…...

JDK、MAVEN与IDEA的安装与配置
1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境,使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载: MAVEN下载传送…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...