操作系统实验:驱动调度 模拟电梯调度算法 C语言实现

一:实验内容

模拟电梯调度算法,对磁盘进行移臂和旋转调度。


二.实验题目

(1).“驱动调度”进程和“接收请求”进程能否占有处理器运行,取决于磁盘的结束中断信 号和处理器调度策略。在实验中可用随机数来模拟确定这两个进程的运行顺序,以代替中断 处理和处理器调度选择的过程。因而,程序的结构可参考下图:

(2).“接收请求”进程建立一张“请求 I/O”表,指出访问磁盘的进程要求访问的物理 地址,表的格式为:

假定某个磁盘组共有 200 个柱面,由外向里顺序编号(0—199),每个柱面上有 20 个 磁道,编号为 0—19,每个磁道分成 8 个物理记录,编号 0—7。进程访问磁盘的物理地址 可以用键盘输入的方法模拟得到。下图 是“接收请求”进程的模拟算法。


三.代码实现

#include<stdio.h>
#include<stdlib.h>#define IOnum 10 //模拟IO表最大长度
struct IO_table
{char Pname; //进程名int Zhu;  //柱面号int Ci; //磁头号int Sha; //扇区号(物理记录)
}IO_table[IOnum],current; //current用于存储每次调度前的上一次访问磁盘的位置int more_current[IOnum] = {-1}; //存储柱面号大于当前柱面号的数组
int more_length = 0;//more数组有效长度
int less_current[IOnum] = {-1}; //存储柱面号小于当前柱面号的数组
int less_length = 0; //less数组有效长度
int processNum = 0; //存储当前IO表中进程总数
int YB_direct = 1; //移臂方向标识符 1表示向内up 0表示向外down  默认向内为1
void IO_table_init() //IO请求表初始化
{int i = 0;  for (i; i < IOnum; i++)//初始化未使用时表内各项数据均为-1{IO_table[i].Pname = '-1';IO_table[i].Zhu = -1;IO_table[i].Ci = -1;IO_table[i].Sha = -1;more_current[i] = -1;less_current[i] = -1;}//模拟预装入8条请求,顺序任意IO_table[0].Pname = 'A'; IO_table[0].Zhu = 58; IO_table[0].Ci = 2; IO_table[0].Sha = 1;//第一个请求IO_table[1].Pname = 'B'; IO_table[1].Zhu = 55; IO_table[1].Ci = 3; IO_table[1].Sha = 2;//第二个请求IO_table[2].Pname = 'C'; IO_table[2].Zhu = 39; IO_table[2].Ci = 4; IO_table[2].Sha = 3;//第三个请求IO_table[3].Pname = 'D'; IO_table[3].Zhu = 38; IO_table[3].Ci = 5; IO_table[3].Sha = 4;//第四个请求IO_table[4].Pname = 'E'; IO_table[4].Zhu = 18; IO_table[4].Ci = 6; IO_table[4].Sha = 5;//第五个请求IO_table[5].Pname = 'F'; IO_table[5].Zhu = 160; IO_table[5].Ci = 7; IO_table[5].Sha = 6;//第六个请求IO_table[6].Pname = 'G'; IO_table[6].Zhu = 150; IO_table[6].Ci = 8; IO_table[6].Sha = 7;//第七个请求IO_table[7].Pname = 'H'; IO_table[7].Zhu = 184; IO_table[7].Ci = 9; IO_table[7].Sha = 0;//第八个请求//模拟预设置 current的值current.Pname = '-1'; current.Zhu = 100; current.Ci = 1; current.Sha = 0;} void show_IO_table()  //打印当前请求IO表
{printf("----------------------[I/O请求表]------------------------\n");int i = 0;for (i; i < IOnum; i++){                    if (IO_table[i].Sha != -1)  //打印非空项{printf("【进程名】:%c", IO_table[i].Pname);printf("  【柱面号】:%3d", IO_table[i].Zhu);printf("  【磁头号】:%d", IO_table[i].Ci);printf("  【扇区号】:%d\n", IO_table[i].Sha);}}printf("----------------------[I/O请求表]------------------------\n");
}int find_inLocation()  //寻找当前IO表中第一个空闲位置,未找到则返回-1
{    int flag = -1;int i = 0;for (i; i < IOnum; i++){if (IO_table[i].Zhu == -1)  //找到IO表中第一个空下标保存并退出{flag = i;break;}}return flag;
}void show_current() //打印选中的current进程,模拟其访问磁盘
{printf("【提示】当前选中进程:");printf("【进程名】:%c", current.Pname);printf("  【柱面号】:%3d", current.Zhu);printf("  【磁头号】:%d", current.Ci);printf("  【扇区号】:%d\n", current.Sha);
}void show_updown()//打印方向
{if (YB_direct == 1)printf("【方向】:up(内)\n");if(YB_direct==0)printf("【方向】:down(外)\n");
}void add_IO_request() //添加新请求
{int flag = -1; //用于标识插入IO表位置flag = find_inLocation();if (flag != -1){printf("【提示】请依次输入【进程名】-【柱面号】-【磁头号】-【扇区号】:\n");scanf("%s%d%d%d", &IO_table[flag].Pname, &IO_table[flag].Zhu, &IO_table[flag].Ci, &IO_table[flag].Sha);}else{printf("【提示】IO表已满");}show_IO_table();//打印修改后的IO表
}int find_zhu(int X) //寻找是否有与X相同的柱面  找到返回其在IO表下标,未找到返回-1
{int flag = -1;int i = 0;for (i; i < IOnum; i++){if (IO_table[i].Zhu ==X) //两柱面相同{flag = i;  //找到符合条件的第一个即返回下标break;}}return flag;
}void sort(int a[],int count)// 直接插入排序 count为数组有效长度,排序为从小到大
{int i, j, temp;for (i = 1; i < count; i++){temp = a[i];j = i - 1;while (a[j] > temp && j >= 0){a[j + 1] = a[j];j--;}if (j != (i - 1))a[j + 1] = temp;}
}
void divide_IO_table() //将IO表按current大小一分为二
{int i = 0, j = 0,t=0;for (t; t < processNum; t++) //当t小于IO表有效长度时{if (IO_table[t].Zhu > current.Zhu)  //找到柱面号大于current的保存{more_current[i] = IO_table[t].Zhu; //添加i++;}if (IO_table[t].Zhu < current.Zhu) //找到柱面号小于current的保存{less_current[j] = IO_table[t].Zhu;j++;}}more_length = i;//保存more有效长度less_length = j ;//保存less有效长度
}
void update_IO_table() //更新IO表信息
{int flag = find_zhu(current.Zhu);//用于标识删除位置int i = 0;if (flag == IOnum - 1)  //若删除的是最后一个{IO_table[flag].Pname = '-1'; IO_table[flag].Zhu = -1; IO_table[flag].Ci = -1; IO_table[flag].Sha = -1;}else {for (i = flag; i < IOnum - 1; i++) //删除非最后一个,数组整体前移{IO_table[i].Pname = IO_table[i + 1].Pname;IO_table[i].Zhu = IO_table[i + 1].Zhu;IO_table[i].Ci = IO_table[i + 1].Ci;IO_table[i].Sha = IO_table[i + 1].Sha;}}
}
void reset_para()//重置各项工作参数
{more_length = 0; less_length = 0;int i = 0;for (i; i < IOnum; i++){more_current[i] = -1;less_current[i] = -1;}
}
void scheduling() //调度程序
{int i = 0;//先检查此时IO表中请求总数processNum = find_inLocation();if (processNum == 0)  //请求表为空{printf("【提示】此时IO表中无等待进程,已退出\n");}//更新currentelse  //请求表不为空{if (find_zhu(current.Zhu) != -1) //找到与current相同柱面的请求{//更新currentcurrent.Pname = IO_table[find_zhu(current.Zhu)].Pname; //进程名current.Ci = IO_table[find_zhu(current.Zhu)].Ci; //磁头号current.Sha = IO_table[find_zhu(current.Zhu)].Sha; //扇区号}else  //未找到相同柱面,采用电梯算法寻找一个合理请求{divide_IO_table();//以current为基准划分IO表,且保存more_current/less_current可作为端点判断//将划分的两个数组进行排序sort(more_current, more_length);sort(less_current, less_length);if (YB_direct == 1) //移臂为1表示此时向内{if (more_length != 0) //即存在比current还大的柱面号{//更新currentcurrent.Pname = IO_table[find_zhu(more_current[0])].Pname;//进程名current.Zhu = IO_table[find_zhu(more_current[0])].Zhu; //柱面号current.Ci = IO_table[find_zhu(more_current[0])].Ci; //磁头号current.Sha= IO_table[find_zhu(more_current[0])].Sha; //扇区号}else  //不存在比current还大的柱面号,需变向{YB_direct = 0;//移臂方向改为向外//按YB=1的方式更新current 模拟变向current.Pname = IO_table[find_zhu(less_current[less_length - 1])].Pname; //进程名current.Zhu = IO_table[find_zhu(less_current[less_length-1])].Zhu; //柱面号current.Ci = IO_table[find_zhu(less_current[less_length-1])].Ci; //磁头号current.Sha = IO_table[find_zhu(less_current[less_length-1])].Sha; //扇区号}}//YB=1if (YB_direct == 0)//移臂为0表示此时向外{if (less_length != 0) //即存在比current还小的柱面号{//更新currentcurrent.Pname = IO_table[find_zhu(less_current[less_length - 1])].Pname;//进程名current.Zhu = IO_table[find_zhu(less_current[less_length - 1])].Zhu; //柱面号current.Ci = IO_table[find_zhu(less_current[less_length - 1])].Ci; //磁头号current.Sha = IO_table[find_zhu(less_current[less_length - 1])].Sha; //扇区号}else  //不存在比current还小的柱面号,需变向{YB_direct = 1;//移臂方向改为向内//按YB=0的方式更新current 模拟变向current.Pname = IO_table[find_zhu(more_current[0])].Pname; //进程名current.Zhu = IO_table[find_zhu(more_current[0])].Zhu; //柱面号current.Ci = IO_table[find_zhu(more_current[0])].Ci; //磁头号current.Sha = IO_table[find_zhu(more_current[0])].Sha; //扇区号}}//YB=0}//打印方向show_updown();//current已更新完-模拟访问磁盘show_current();//打印current//更新IO表,即删除此次访问项update_IO_table();//重置各项辅助参数reset_para();//打印本次执行后IO表show_IO_table();}
}
void main()
{IO_table_init(); //初始化show_IO_table(); //打印初始IO请求表int select = -1; //选择标识符printf("【提示】请选择要执行的操作:(0->驱动调度:1->接收进程)");scanf("%d", &select);while (1) {    printf("【提示】当前磁盘位置:");printf("【进程名】:%c", current.Pname);printf("  【柱面号】:%3d", current.Zhu);printf("  【磁头号】:%d", current.Ci);printf("  【扇区号】:%d\n", current.Sha);if(select==0)scheduling(); //调用驱动程序if (select == 1)add_IO_request();//接受进程printf("【提示】请选择要执行的操作:(0->驱动调度:1->接收进程)");scanf("%d", &select);}system("pause");
}


四.运行结果

【初始化IO表并打印】

【进行一次驱动调度】当前current.Zhu=100

可发现“选中进程”已从IO请求表中移除。

 【进行一次驱动调度】当前current.Zhu=150

观察可发现“选中进程”已从IO请求表中移除

【进行一次接受进程】当前current.Zhu=160

可发现模拟新请求已插入到请求表中


 五.流程图

(1.)scheduling()调度函数

(2).电梯调度算法

 

 

 

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

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

相关文章

Java实现电梯调度算法

Java实现电梯调度算法 电梯算法简介题目代码实现效果图 电梯算法简介 当磁头正在由里向外移动时&#xff0c;电梯调度算法所选择的下一个访问对象应是其欲访问的磁道&#xff0c;既在当前磁道之外&#xff0c;又是距离最近的。这样由里向外地访问&#xff0c;直至再无更外的磁道…

算法高级(39)-坐电梯时情不自禁想起的电梯调度算法实现原理

一、引言 现代社会中&#xff0c;不管你是在北上广、北海道、新加坡&#xff0c;或者是三四五六七八线的小城市&#xff0c;凡是有点规模的地方&#xff0c;高楼大厦都是比比皆是的。而在上下楼的时候&#xff0c;不可避免的会跟电梯打交道。而一般情况你也很少能心平气和地等…

电梯调度

在像芝加哥&#xff0c;纽约&#xff0c;东京&#xff0c;新加坡&#xff0c;香港等大城市里&#xff0c;每天都会有上百万的人通过电梯离开他们的大楼。但是我们却很少考虑电梯是如何调度来提供服务的&#xff0c;尤其是在人流高峰期&#xff0c;这个时候办公楼里的大多数人都…

电梯调度算法

磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器&#xff0c;担负着繁重的输入输出任务、在多道程序设计系统中&#xff0c;往往同时会有若干个要求访问磁盘的输入输出请求等待处理&#xff0c;这时我们就需要采用一种合适的调度算法来使…

苹果主屏幕按钮怎么设置_苹果手机屏幕变大怎么恢复

如果苹果手机屏幕放大起来&#xff0c;其实只要同时使用三个手指快速连续点击手机屏幕两次&#xff0c;手机界面就会恢复正常。还可以在【设置】-【通用】-【辅助功能】中将【缩放】开关关闭。在【辅助功能】中【更大字体】选项中可以调整字体的大小。具体介绍如下&#xff1a;…

苹果主屏幕按钮怎么设置_Mac小技巧 Mac屏幕旋转怎么设置

相信不少的Mac用户在躺下看电子书或者电影的时候&#xff0c;都希望可以将Mac的电脑屏幕进行旋转&#xff01;其实&#xff0c;这个操作是可以实现的呢&#xff01;那么&#xff0c;你知道Mac屏幕旋转怎么设置吗&#xff1f;想要知道答案的话就快来阅读下面的文章吧&#xff01…

苹果屏幕旋转怎么设置_iPhone12屏幕供应商是谁 苹果12屏幕怎么查看是哪家

苹果iPhone12系列手机在10月份正式发售上市&#xff0c;今年的iPhone12全系列都使用了OLED屏幕&#xff0c;官方将这块屏幕称之为超视网膜 XDR 显示屏&#xff0c;那么今年的iPhone12系列屏幕供应商有哪些&#xff0c;怎么分辨自己手上的iPhone12屏幕来自哪家公司呢&#xff0c…

苹果手机投屏软件_苹果手机怎样投屏到笔记本?

注&#xff1a;本文转载自网络&#xff0c;不代表本平台立场&#xff0c;仅供读者参考&#xff0c;著作权属归原创者所有。我们分享此文出于传播更多资讯之目的。如有侵权&#xff0c;请在后台留言联系我们进行删除&#xff0c;谢谢&#xff01; 经常用手机的小伙伴都知道&am…

怎么设置苹果手机的小圆点_苹果屏幕旋转怎么设置?关于苹果手机设置的一些小技巧...

苹果屏幕旋转怎么设置&#xff1f;在平常使用手机观看视频的时候&#xff0c;很多人希望手机屏幕可以自己旋转为横屏状态&#xff0c;在使用微信聊天的时候再自动转为竖屏&#xff0c;这种切换可以直接利用控制中心的一个功能来实现。 如何开启苹果手机的屏幕旋转&#xff1f;首…

苹果屏幕使用时间怎么设置_苹果手机屏幕不能旋转怎么办

很多刚刚接触苹果手机的人&#xff0c;可能不知道怎么使用苹果手机。那么苹果手机屏幕不能旋转怎么办呢&#xff1f;下面就让小编来告诉大家吧&#xff0c;欢迎阅读。 1、苹果手机页面未锁定的情况下从屏幕底端向上滑动&#xff0c;弹出小界面窗口。 2、可以看到小窗口顶部左端…

linux屏幕旋转后触控不准,手机重力感应失效解决方法 不能自动旋转屏幕怎么设置...

如今手机已经成为人们生活中必不可少的一个工具了&#xff0c;在使用过程也常常会遇到各种各样的问题&#xff0c;比如当手机重力感应失效的时候应该怎么解决呢&#xff0c;手机不能自动旋转屏幕要怎么设置&#xff0c;针对这个问题下面就为大家带来最新解决方法&#xff0c;希…

苹果6怎样打开html,苹果6屏幕旋转怎么设置 怎么开启和关闭【图文】

手机在使用的过程中&#xff0c;通常都会有两种状态&#xff0c;横屏与竖屏&#xff0c;大家的使用习惯不一样&#xff0c;所喜欢的状态也不一样&#xff0c;而且手机都会有屏幕自动旋转的情况&#xff0c;它会根据手机的摆放状态自己切换&#xff0c;比较方便大家使用&#xf…

会员管理系统,建议收藏!

你见过会员管理系统吗&#xff1f;在一些线下的美容院&#xff0c;健身房&#xff0c;理发店&#xff0c;往往会有办理会员这样的需求&#xff0c;所以会员管理系统应运而生。那会员管理系统有哪些作用呢&#xff1f; 会员卡&#xff1a;无需填写信息、无需实体会员卡&#xf…

会员卡系统的管理运营

下面的是会员系统的源代码和DOS命令的运行

会员卡应用管理系统源码 支持收银+积分管理+商城营销功能 含详细搭建教程

分享一个会员卡应用管理系统源码&#xff0c;收银积分管理商城营销系统源码&#xff0c;含完整的程序包和搭建教程。 系统功能一览&#xff1a; 1、精简强悍&#xff0c;会员卡&#xff0c;积分&#xff0c;在线充值&#xff0c;商家核销&#xff0c;在线下单&#xff0c;优惠…

C语言:会员管理系统

会员信息包括&#xff1a;会员号&#xff08;6位数&#xff0c;唯一&#xff09;&#xff0c;姓名&#xff0c;身份证号&#xff0c;联系电话&#xff0c;状态&#xff08;1表示正常&#xff0c;0表示挂失&#xff09;。 会员管理包括&#xff1a;会员的添加、删除、修改&#…

云上铺会员管理系统支持什么类型会员卡?

最近很多打算购买我们系统的客户都在问我们&#xff0c;云上铺到底支持什么会员卡&#xff0c;今天趁这个机会专门给大家讲一下。 云上铺会员管理系统&#xff0c;作为一款独立开发设计的SAAS会员管理系统&#xff0c;广泛适用于美容美发&#xff0c;汽车美容&#xff0c;服装…

C语言 会员管理系统

大一上学期期末项目设计&#xff1b; 思路参考&#xff1a;【千锋教育新版C语言程序设计视频教程&#xff08;适合自学&#xff0c;c语言初学者入门教程&#xff09;】 https://www.bilibili.com/video/BV1id4y1375a/?p119&share_sourcecopy_web&vd_sourcea6401c9820…

微信会员卡管理系统会员充值说明

云上铺微信会员卡管理系统会员充值即会员卡储值进行余额消费一种操作。 基础操作&#xff1a;点击【消费收银】→【会员充值】&#xff0c;显示有【会员充值/扣款/转账/提现】等业务&#xff0c;如下图所示&#xff1a; 会员充值必须先选择会员信息,输入会员卡号&#xff0c;或…