模拟电梯调度算法实现对磁盘的驱动调度
磁盘驱动调度算法的模拟

实验四磁盘驱动调度算法的模拟一.实验内容:熟悉磁盘的结构以及磁盘的驱动调度算法的模拟,编程实现简单常用的磁盘驱动调度算法先来先服务(FIFO)、电梯调度算法、最短寻找时间优先算法、扫描(双向扫描)算法、单向扫描(循环扫描)算法等。
编程只需实现两个算法。
题目可以选取教材或习题中的相关编程实例。
编程语言建议采用c/c++或Java。
模拟程序鼓励采用随机数技术、动态空间分配技术,有条件的最好能用图形界面展现甚至用动画模拟。
实验性质:验证型。
二.实验目的和要求1)掌握使用一门语言进行磁盘驱动调度算法的模拟;2)编写程序将磁盘驱动调度算法的过程和结果能以较简明直观的方式展现出来。
三.实验原理、方法和步骤1. 实验原理磁盘驱动调度对磁盘的效率有重要影响。
磁盘驱动调度算法的好坏直接影响辅助存储器的效率,从而影响计算机系统的整体效率。
常用的磁盘驱动调度算法有:最简单的磁盘驱动调度算法是先入先出(F IFO)法。
这种算法的实质是,总是严格按时间顺序对磁盘请求予以处理。
算法实现简单、易于理解并且相对公平,不会发生进程饿死现象。
但该算法可能会移动的柱面数较多并且会经常更换移动方向,效率有待提高。
最短寻找时间优先算法:总是优先处理最靠近的请求。
该算法移动的柱面距离较小,但可能会经常改变移动方向,并且可能会发生进程饥饿现象。
电梯调度:总是将一个方向上的请求全部处理完后,才改变方向继续处理其他请求。
扫描(双向扫描):总是从最外向最里进行扫描,然后在从最里向最外扫描。
该算法与电梯调度算法的区别是电梯调度在没有最外或最里的请求时不会移动到最外或最里柱面,二扫描算法总是移到最外、最里柱面。
两端的请求有优先服被务的迹象。
循环扫描(单向扫描):从最外向最里进行柱面请求处理,到最里柱面后,直接跳到最外柱面然后继续向里进行处理。
该算法与扫描算法的区别是,回来过程不处理请求,基于这样的事实,因为里端刚被处理。
2. 实验方法1)使用流程图描述演示程序的设计思想;2)选取c/c++、Java等计算机语言,编程调试,最终给出运行正确的程序。
驱动调度算法

驱动调度算法一、实验目的磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。
他作为计算机系统的辅助存储器,担负着输入输出任务,在多道程序设计系统中,往往同时会有这若干个要求访问磁盘的输入输出请求等待处理。
系统课采用一种策略,尽可能按最佳次序执行要求访问磁盘的诸多输入输出请求。
这就叫驱动调度,使用的算法叫驱动算法。
二,实验内容模拟电梯调度算法,实现对磁盘的驱动调度。
三,源程序#include<stdio.h>#include<stdlib.h>#include<iostream.h>#include<math.h>#define maxsize 1000int decide(char str[]) //判断输入数据是否有效{int i=0;while(str[i]!='\0'){if(str[i]<'0'||str[i]>'9'){return 0;break;}i++;}return i;}int trans(char str[],int a) //将字符串转换成数字{int i;int sum=0;for(i=0;i<a;i++){sum=sum+(int)((str[i]-'0')*pow(10,a-i-1));}return sum;}int *bubble(int cidao[],int m){int i,j;int temp;for(i=0;i<m;i++) //使用冒泡法按从小到大顺序排列for(j=i+1;j<m;j++){if(cidao[i]>cidao[j]){temp=cidao[i];cidao[i]=cidao[j];cidao[j]=temp;}}cout<<"排序后的磁盘序列为:";for( i=0;i<m;i++) //输出排序结果{cout<<cidao[i]<<" ";}cout<<endl;return cidao;}void FCFS(int cidao[],int m) //先来先服务调度算法{int now; //当前磁道号int sum=0; //总寻道长度int j,i;int a;char str[100];float ave; //平均寻道长度cout<<"磁盘请求序列为:";for( i=0;i<m;i++) //按先来先服务的策略输出磁盘请求序列{cout<<cidao[i]<<" ";}cout<<endl;cout<<"请输入当前的磁道号:";B: cin>>str; //对输入数据进行有效性判断a=decide(str);if(a==0){cout<<"输入数据的类型错误,请重新输入!"<<endl;goto B;}elsenow=trans(str,a); //输入当前磁道号sum+=abs(cidao[0]-now);cout<<"磁盘扫描序列为:";for( i=0;i<m;i++) //输出磁盘扫描序列{cout<<cidao[i]<<" ";}for(i=0,j=1;j<m;i++,j++) //求平均寻道长度{sum+=abs(cidao[j]-cidao[i]);ave=(float)(sum)/(float)(m);}cout<<endl;cout<<"平均寻道长度:"<<ave<<endl;}void SSTF(int cidao[],int m) //最短寻道时间优先调度算法{int k=1;int now,l,r;int i,j,sum=0;int a;char str[100];float ave;cidao=bubble(cidao,m); //调用冒泡排序算法排序cout<<"请输入当前的磁道号:";C: cin>>str; //对输入数据进行有效性判断a=decide(str);if(a==0){cout<<"输入数据的类型错误,请重新输入!"<<endl;goto C;}elsenow=trans(str,a); //输入当前磁道号if(cidao[m-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务{cout<<"磁盘扫描序列为:";for(i=m-1;i>=0;i--)cout<<cidao[i]<<" ";sum=now-cidao[0];}if(cidao[0]>=now) //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务{cout<<"磁盘扫描序列为:";for(i=0;i<m;i++)cout<<cidao[i]<<" ";sum=cidao[m-1]-now;}if(now>cidao[0]&&now<cidao[m-1]) //若当前磁道号大于请求序列中最小者且小于最大者{cout<<"磁盘扫描序列为:";while(cidao[k]<now) //确定当前磁道在已排的序列中的位置,后面的算法都用到了,可以直接复制后少量修改,节省时间。
操作系统驱动调度

操作系统实习报告姓名学号日期实验室指导教师设备编号实习题目实习九驱动调度一、实习内容模拟电梯调度算法,实现对磁盘的驱动调度。
二、实习目的磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。
它作为计算机系统的辅助存储器,担负着繁重的输入输出任务、在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请求等待处理。
系统可采用一种策略,尽可能按最佳次序执行要求访问磁盘的诸输入输出请求。
这就叫驱动调度,使用的算法称为驱动调度算法。
驱动调度能降低为若干个输入输出请求服务所需的总时间,从而提高系统效率。
本实验要求学生模拟设计一个驱动调度程序,观察驱动调度程序的动态运行过程。
通过实验使学生理解和掌握驱动调度的职能。
三、实习过程1.数据结构设计#define M 20typedef struct PCB{charproc[M];//进程名int cylinder_num;//柱面号int track_num;//磁道号int phy_num;//物理记录号struct PCB *next;}PCB;2.算法设计(1) 主函数框图如图1.1)主函数要求用户选择大于0.5 <电梯调度>小于0.5 <接受请求>2)进入模拟程序调用函数对输入值进行判定。
3)输入值大于0.5 初始化数组。
调用lift( )函数。
调用电梯调度算法。
调用输出函数output。
4)输入值小于0.5 调用接受请求函数。
接受进程输入请求,写入链表。
调用输出函数output。
5)要求用户选择是否继续Y.继续N.退出(2) 电梯调度算法lift() 如图3.1) 查I/O请求表,若等待进程表中有进程,则继续。
否则返回。
2) 若有与当前运行的进程的柱面号相同的进程访问,则选择能使旋转距离最短的访问者,并登记当前位置。
否则继续判断当前移臂方向。
3) 若当前移臂方向向里,则判断是否有比当前柱面号大的访问请求;否则判断是否有比当前柱面号小的访问请求。
实验二 模拟实现磁盘调度算法

实验二模拟实现磁盘调度算法姓名:班级:软件工程二班学号:日期:2020年12月13日实验目的:a、观察、体会操作系统的磁盘调度方法,并通过一个简单的磁盘调度模拟程序的实现,加深对磁盘调度的理解。
b、提高实际动手编程能力,为日后从事软件开发工作打下坚实基础。
实验内容:a、模拟实现磁盘调度算法:FCFS,最短寻道优先,电梯算法(参照给定的算法实现最短寻道优先算法,电梯算法(磁头向外))。
b、磁道请求服务顺序由用户输入(可通过从指定的文本文件(TXT文件)中取出)。
基本思想、原理和算法描述:(1)电梯算法磁头初始向外:思想和原理:用户输入一个初始磁道号,规定向外和向内,向外即先逐渐减小,当向外遍历完后,就掉头向里,向里则是逐渐增大。
设置一个变量了定义进程是否已经执行,每执行完一个就给它赋值,下次就不遍历。
算法描述:首先调用重置访问标志、磁头当前位置、总移动磁道数的函数,然后进入循环,在循环刚开始时候,定义一个非常大的容器用来存储移动磁道数。
比较移动磁道数的大小,把小的那个磁道的下标给iNEXT,并把移动磁道数改为当前磁道的磁道移动数,用于下一次比较。
然后累加总移动磁道数,移动磁头当前位置为当前访问磁道号,并设置磁道是否已经访问标志为1:已访问。
(2)最短寻道优先调度算法:思想和原理:要求访问的磁道与当前磁头所在的磁道距离最近,即要求移动的磁道数最小的后一个磁道先执行。
主要是比较下一个磁道与当前磁道的差,取差最小的那个磁道,后面以此类推。
算法描述:源程序和电梯算法相似,本算法只比较移动磁道数的大小。
循环比较,直到所有的磁道都遍历完。
源程序:(1)电梯算法磁头初始向外:case 2://磁头初始向外Reset();//重置访问标志、磁头当前位置、总移动磁道数cout<<endl<<"---------------------------------------------"<<endl;cout<<"电梯调度算法——磁头初始向外的调度结果: "<<endl<<endl;cout<<"初始磁道号: "<<iStart<<endl;cout<<"序号下一磁道号移动的磁道数"<<endl;for(i=0;i<iReqNum;i++){iMinMove=9999;iNext=-1;for(j=0;j<iReqNum;j++)//寻找当前方向上寻道距离最短的未访问磁道号在数组队列queue中的下标{if((queue[j].iBeVisited==0)&&(queue[j].iGo<=iNow)){if(abs(queue[j].iGo-iNow)<iMinMove){iNext=j;iMinMove=abs(queue[j].iGo-iNow);} //if(abs(queue[j].iGo-iNow)<iMinMove)} //if((queue[j].iBeVisited==0)&&(queue[j].iGo>=iNow))} //for(j=0;j<iReqNum;j++)if(iNext!=-1){//输出信息摸拟访问请求的磁道cout<<" "<<i+1<<" "<<queue[iNext].iGo<<" "<<abs(queue[iNext].iGo-iNow)<<endl;iSum+=abs(queue[iNext].iGo-iNow);//累加总移动磁道数iNow=queue[iNext].iGo;//移动磁头当前位置为当前访问磁道号queue[iNext].iBeVisited=1;//设置磁道是否已经访问标志为1:已访问} //if(iNext!=-1)else//掉头向外{for(j=0;j<iReqNum;j++)//寻找当前方向上寻道距离最短的未访问磁道号在数组队列queue中的下标{if((queue[j].iBeVisited==0)&&(queue[j].iGo>iNow)){if(abs(queue[j].iGo-iNow)<iMinMove){iNext=j;iMinMove=abs(queue[j].iGo-iNow);}}} //for(j=0;j<iReqNum;j++)//输出信息摸拟访问请求的磁道cout<<".."<<i+1<<"……"<<queue[iNext].iGo<<"…"<<abs(queue[iNext].iGo-iNow)<<endl;iSum+=abs(queue[iNext].iGo-iNow);//累加总移动磁道数iNow=queue[iNext].iGo;//移动磁头当前位置为当前访问磁道号queue[iNext].iBeVisited=1;//设置磁道是否已经访问标志为1:已访问} //if(iNext!=-1)} //for(i=0;i<iReqNum;i++)cout<<endl<<"总调度次数: "<<iReqNum<<endl;cout<<endl<<"总移动磁道数: "<<iSum<<endl;printf("\n平均移动磁道数: %.2f\n\n",(float)iSum / (float)iReqNum);break;default:printf("\n输入错误!!\n\n");return;}//switch(iInput)}运行结果:(2)最短寻道优先调度算法:void SSTF() //最短寻道优先调度算法{Reset();//重置访问标志、磁头当前位置、总移动磁道数cout << endl << "---------------------------------------------" << endl;cout << "最短寻道优先调度算法的调度结果: " << endl << endl;cout << "初始磁道号: " << iStart << endl;cout << "序号下一磁道号移动的磁道数" << endl;int numberend = 0;//已经运行的磁道的数目int size = 0;//当前磁道与某磁道的距离int NewiNow = 0;//记录与当前磁头距离最短的磁道的下标,初始化为0while (numberend != iReqNum)//已经运行的磁道的数目超出最大数目时退出循环{for (int i = 0; i < iReqNum; i++){if (!queue[i].iBeVisited){size = abs(iNow - queue[i].iGo);//初始化当前距离NewiNow = i;//跟新下标break;}}for (int i = 0; i < iReqNum; i++)//循环遍历,在为输出的磁道中寻找与当前磁道最近的磁道{if (!queue[i].iBeVisited&&size > abs(iNow - queue[i].iGo))//如果该磁道没有被访问,且距离小于当前距离{size = abs(iNow - queue[i].iGo);//更新磁道距离NewiNow = i;//跟新下标}}queue[NewiNow].iBeVisited = 1;//标记该磁道已访问iNow = queue[NewiNow].iGo;//移动磁头当前位置为当前访问磁道号iSum += size;//累加总移动磁道数++numberend;//更新已经访问磁道数目//输出信息摸拟访问请求的磁道cout << " " << numberend << " " << iNow << " " << size << endl;}cout << endl << "总调度次数: " << iReqNum << endl;cout << endl << "总移动磁道数: " << iSum << endl;printf("\n平均移动磁道数: %.2f\n\n", (float)iSum / (float)iReqNum);}运行结果分析:(2)最短寻道优先调度算法:实验总结:深刻理解FCFS,最短寻道优先,电梯算法。
磁盘移臂调度过程模拟设计-电梯算法_最短寻道时间优先

学号:课程设计题目磁盘移臂调度过程模拟设计--电梯算法、最短寻道时间优先算法学院计算机科学与技术学院专业班级姓名指导教师吴利军2013 年 1 月15 日课程设计任务书学生姓名:指导教师:吴利军工作单位:计算机科学与技术学院题目: 磁盘移臂调度过程模拟设计——电梯算法、最短寻道时间优先算法初始条件:1.预备内容:阅读操作系统的文件管理章节内容,理解有关文件组织形式、存储设备的概念。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.编程序模拟磁盘调度的过程,采用指定算法,模拟并输出存取臂的移动顺序,并计算存取臂移动的磁道总数。
能够处理以下的情形:⑴可根据需要输入当前磁头的位置,磁头移动方向;⑵能够输入柱面数,磁道访问序列等参数,并能够显示调度结果(磁盘访问请求的磁道号以及磁头移动的总磁道数)。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收,撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日磁盘移臂调度过程模拟设计——电梯算法、最短寻道时间优先算法1 课程设计目的与功能操作系统课程设计,主要是在学习操作系统课程并完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,进一步分析各个部分之间的联系,以达到对完整系统的理解。
驱动调度算法

一.模拟电梯调度算法,实现对磁盘的驱动调度二.程序中使用的数据结构及其说明typedefstruct Process//描述进程信息{char name[N]。
//进程名int cyl_num。
//请求的柱面号int tra_num。
//请求的磁道号int rec_num。
//请求的物理记录号int signal。
//标记位}process。
三.源程序及注释pro_struct.h#ifndef PRO_STRUCT_H#define PRO_STRUCT_H#define N 10typedefstruct Process//描述进程信息{char name[N]。
//进程名int cyl_num。
//请求的柱面号int tra_num。
//请求的磁道号int rec_num。
//请求的物理记录号int signal。
//标记位}process。
#endifpro_list.h#ifndef PRO_LIST_H#define PRO_LIST_H#include<iostream>#include<string.h>#include"pro_struct.h"usingnamespace std。
#define M 100void list(int pro_count,int pro_num,process pro[M]>//创建等待进程表b5E2RGbCAP{cout<<"等待的进程数:"。
cin>>pro_num。
if(pro_num>0&&(pro_num+pro_count><=M>//判断要输入的进程数是否合法,输入后是否超出进程等待表所允许的最大值p1EanqFDPw {cout<<"开始输入"<<endl。
磁盘驱动调度算法

磁盘驱动调度算法磁盘驱动调度算法是操作系统中的一种重要机制,用于决定磁盘上的数据访问顺序,提高磁盘的读写效率。
在计算机系统中,磁盘是一种主要的存储介质,而磁盘驱动调度算法则是决定计算机系统如何合理地利用磁盘资源的关键。
磁盘驱动调度算法的目标是通过合理地安排磁盘上的数据访问顺序,最大限度地提高磁盘的读写效率。
在实际应用中,磁盘上的数据往往是分散存储的,即不同的文件、目录等数据被存储在不同的磁盘块中。
因此,当系统需要读取或写入某个文件时,需要将磁头移动到相应的磁道上,然后再进行数据的读取或写入操作。
而磁盘驱动调度算法的任务就是决定磁头的移动顺序,从而提高磁盘的访问效率。
常见的磁盘驱动调度算法有先来先服务(FCFS)、最短寻道时间优先(SSTF)、电梯调度算法(SCAN)、循环扫描算法(C-SCAN)等。
下面将逐一介绍这些算法的特点和应用场景。
1. 先来先服务(FCFS)算法:该算法按照磁盘请求的先后顺序进行调度,即先到达磁盘的请求先被服务。
这种算法简单直接,但由于没有考虑磁盘的物理结构和磁头的移动距离等因素,可能会导致磁盘的平均寻道时间较长。
2. 最短寻道时间优先(SSTF)算法:该算法会选择离当前磁道最近的请求进行服务,从而减少磁头的移动距离,提高磁盘的读写效率。
然而,这种算法可能会出现饥饿现象,即某些请求长时间得不到服务。
3. 电梯调度算法(SCAN):该算法模拟了电梯的运行过程,磁头按照一个方向移动,直到到达磁盘的边界,然后改变方向继续移动。
这种算法能够有效地减少磁头的移动次数,提高磁盘的读写效率。
但由于磁头只能按照一个方向移动,可能会导致某些请求长时间得不到服务。
4. 循环扫描算法(C-SCAN):该算法是电梯调度算法的一种改进,磁头按照一个方向移动,直到到达磁盘的边界,然后立即返回到起始位置,继续移动。
这种算法能够有效地减少磁头的移动距离,提高磁盘的读写效率。
不同的磁盘驱动调度算法适用于不同的应用场景。
模拟电梯调度算法概要

一、课程设计目的了解驱动调度程序的动态运行过程, 理解和掌握驱动调度的职能。
驱动调度能降低为若干个输入输出请求服务所需的总时间,从而提高系统功能。
二、软硬件环境1.软件配置windows.xp 、 TURBOC2。
2. 硬件配置内存 256; CPU inter pentinum®4 2.80G 赫兹。
三、系统设计及开发过程1. 系统具体设计过程(1.模拟电梯调度算法, 对磁盘进行移臂和旋转调度, 使进程访问磁盘, 他们实现过程是:通过随机函数产生 [0, 1]之间随机数, 判断这个随机数是不是大于 0.5, 是, 则执行驱动调度,否,则执行接受请求(2 . 假定随机数大于 0.5,则执行驱动调度,在屏幕输出当前请求 I/O表中的等待进程, 然后输出选中进程名, 访问的柱面号, 物理记录和当前移臂方向。
(3 . 假定随机数小于 0.5,则执行接受请求。
将输入的进程的物理地址排入等待队列,写入请求I/O表中。
2. 主要数据结构设计为了记录进程访问磁盘请求的情况, 以及进程访问磁盘状态信息, 我们设计了请求 I/O表结构体 askb ,请求 I/O表包括四项int name 进程名 //标志进程的名字;int zmh 柱面号 //当前磁臂所在柱面号;int wj 物理记录 //当前磁臂所在物理记录号;int fx 方向 //移臂方向,向里,向外;用请求 I/O表定义了请求 I/O表 W[1600],全局型变量 M 。
1、私有成员(1、结构体型数组 b[1600]充当等待队列;(2、两个变量 m , n 记录最后访问柱面号,物理记录号(3、变量 cont 记录输入请求的个数;(4、数组 flag[1600]记录移臂方向;(5、 M 是接受请求输入的中间量;(6、 l,h 记录选中进程数2、公有成员(1、 jieshou ( 将输入的请求访问磁盘的进程的进程名,柱面号及物理记录写入请求 I/O表中,变量 g 加 1;(2、 driver( 沿臂移动方向选择离当前旋转或移臂距离最短的等待访问进程(3、 print( 输出当前请求 I/O表中的等待访问进程, 并输出选中的进程名, 访问柱面号,物理记录号3. 算法设计主要函数说明及其流程图函数名 main( 如图 1主程序流程所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验(第三次)一、实验内容模拟电梯调度算法,实现对磁盘的驱动调度。
二、实验目的磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。
它作为计算机系统的辅助存储器,担负着繁重的输入输出任务、在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请求等待处理。
系统可采用一种策略,尽可能按最佳次序执行要求访问磁盘的诸输入输出请求。
这就叫驱动调度,使用的算法称为驱动调度算法。
驱动调度能降低为若干个输入输出请求服务所需的总时间,从而提高系统效率。
本实验要求学生模拟设计一个驱动调度程序,观察驱动调度程序的动态运行过程。
通过实验使学生理解和掌握驱动调度的职能。
三、实验题目模拟电梯调度算法,对磁盘进行移臂和旋转调度。
[提示]:(1)磁盘是可供多个进程共享的存储设备,但一个磁盘每时刻只能为一个进程服务。
当有进程在访问某个磁盘时,其他想访问该磁盘的进程必须等待,直到磁盘一次工作结束。
当有多个进程提出输入输出要求而处于等待状态时,可用电梯调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。
选择访问者的工作由“驱动调度”进程来完成。
由于磁盘与处理器是可以并行工作的、所以当磁盘在作为一个进程服务时,占有处理器的另一进程可以提出使用磁盘的要求,也就是说,系统能动态地接收新的输入输出请求。
为了模拟这种情况,在本实验中设置了一个“接收请求”进程。
“驱动调度”进程和“接收请求”进程能否占有处理器运行,取决于磁盘的结束中断信号和处理器调度策略。
在实验中可用随机数来模拟确定这两个进程的运行顺序,以代替中断四、处理和处理器调度选择的过程。
因而,程序的结构可参考图3—1(2)“接收请求”进程建立一张“请求I/O”表,指出访问磁盘的进程要求访问的物理地址,表的格式为:假定某个磁盘组共有200 个柱面,由外向里顺序编号(0—199),每个柱面上有20 个磁道,编号为0—19,每个磁道分成8 个物理记录,编号0—7。
进程访问磁盘的物理地址可以用键盘输入的方法模拟得到。
图3—2 是“接收请求”进程的模拟算法。
在实际的系统中必须把等待访问磁盘的进程排入等待列队,由于本实验模拟驱动调度,为简单起见,在实验中可免去队列管理部分,故设计程序时可不考虑“进程排入等待队列”的工作。
(3)“驱动调度”进程的功能是查“请求I/O”表,当有等待访问磁盘的进程时,按电梯调度算法从中选择一个等待访问者,按该进程指定的磁盘物理地址启动磁盘为其服务。
对移动臂磁盘来说,驱动调度分移臂调度和旋转调度。
电梯调度算法的调度策略是与移动臂的移动方向和移动臂的当前位子有关的,所以每次启动磁盘时都应登记移动臂方向和当前位子。
电梯调度算法是一种简单而实用的驱动调度方法,这种调度策略总是优先选择与当前柱面号相同的访问请求,从这些请求中再选择一个能使旋转距离最短的等待访问者。
如果没有与当前柱面号相同的访问请求,则根据移臂方向来选择,每次总是沿臂移动方向选择一个与当前柱面号最近的访问请求,若沿这个方向没有访问请求时,就改变臂的移动方向。
这种调度策略能使移动臂的移动频率极小,从而提高系统效率。
用电梯调度算法实现驱动调度的模拟算法如图3-3。
(4)图3-1 中的初始化工作包括,初始化“请求I/O”表,置当前移臂方向为里移;置当前位置为0 号柱面,0 号物理记录。
程序运行前可假定“请求I/O”表中已经有如干个进程等待访问磁盘。
在模拟实验中,当选中一个进程可以访问磁盘时,并不实际地启动磁盘,而用显示:“请求I/O”表;当前移臂方向;当前柱面号,物理记录号来代替图3-3 中的“启动磁盘”这项工作。
(1)程序中使用的数据结构及其说明。
(2)const int PCB=100; ylinder != NULL; i++)(3){(4)}(5)cout << i << endl;(6)return i;(7)}(8)void accept() name >> pcbs[pcbs_num].Cylinder >> pcbs[pcbs_num].Track >>pcbs[pcbs_num].Record;(9)pcbs_num++;(10)}(11)int Cylinder_e() ylinder ==(12)return i;(13)}(14)return 0;(15)}(16)int Cylinder_near(int cylinder, int record) ylinder == cylinder)(17){(18) a = pcbs[i].Record - record;(19)if (a<0){ a = a + 8; }(20)if (a<t)(21){(22)t = a; k = i;(23)}(24)}(25)}(26)return k;(27)}(28)int Cylinder_max(int cylinder) ylinder - cylinder))<t && pcbs[i].Cylinder > cylinder)(29){(30)t = abs(pcbs[i].Cylinder - cylinder);(31)}(32)} num = cylinder + t; ylinder == num &&pcbs[i].Record < t)(33){(34)t = pcbs[i].Record; a = i;(35)}(36)}(37)return a;(38)}(39)int Cylinder_max1(int cylinder)(40){(41)int t = 199, i, b = 0, c = 0;(42)for (i = 0; i<pcbs_num; i++)(43){(44)if((abs(pcbs[i].Cylinder - cylinder))>b && pcbs[i].Cylinder > cylinder)(45){(46) b = abs(pcbs[i].Cylinder - cylinder);(47)}(48)}(49)return b;(50)}(51)int Cylinder_min(int cylinder) ylinder - cylinder))<t && pcbs[i].Cylinder < cylinder)(52){(53)t = abs(pcbs[i].Cylinder - cylinder);(54)}(55)}(56)num = cylinder - t; t = 8; ylinder == num && pcbs[i].Record <t)(57){(58)t = pcbs[i].Record; a = i;(59)}(60)}(61)return a; name << setfill(' ') << setw(8) << pcbs[i].Cylinder << setfill(' ') << setw(8) << pcbs[i].Track << setfill(' ') << setw(10) << pcbs[i].Record << endl;(62)}(63)}(64)void print_scan(bool x)(65){(66)cout << "选中的:"<< endl; cout << "进程名"<< " 柱面号"<< " 磁道号"<< " 物理记录号" << " 方向" << endl; cout << setfill(' ') << setw(6) << << setfill(' ') << setw(8) << << setfill(' ') << setw(10) << << setfill(' ') << setw(10) << << setfill(' ') << setw(6) << x << endl;(67)}(68)int SCAN() ylinder == ylinder<(69){(70)way = 0;(71)}(72)else way = 1;(73)}(74)else(75){(76)if (way == 1)(77){(78)scan = Cylinder_max; //选择比当前柱面号大的请求中物理块号最小的(79)scan1 = Cylinder_max1;(80)if (scan == scan1)(81){(82)scan = Cylinder_min; //选择比当前柱面号小的请求中物理块号最大的(83)way = 0;(84)}(85)}(86)else(87){(88)scan = Cylinder_min;(89)if (scan == 0)(90){(91)scan = Cylinder_max;(92)way = 1;(93)}(94)}(95)} a = pcbs[scan];(96)delete_scan(scan); //删除pcbs[scan](97)print_scan(way); //打印(98)return 1;(99)}(100)}(101)void work()//初始化(102){(103)float n; char y = 'y'; while (y == 'y' || y == 'Y') (104){(105)cout << "输入在[0,1]区间内的一个随机数" << endl; (106)cin >> n;(107)if (n>(108){(109)SCAN(); //驱动调度(110)}(111)else(112){(113)accept(); //接受请求(114)}(115)cout << "继续(y/n)" << endl;(116)cin >> y;(117)}(118)}(119)void main()(120){(121)work();(122) }(4)打印驱动调度进程每次选择访问请求前的“请求I/O”表以及每次选中的进程名、访问的柱面号、物理记录号和当前移臂方向(用up 代表里移,down 代表外移。