第一篇:操作系统进程调度算法模拟实验报告
进程调度算法模拟
专业:XXXXX 学号:XXXXX 姓名:XXX 实验日期:20XX年XX月XX日
一、实验目的
通过对进程调度算法的模拟加深对进程概念和进程调度算法的理解。
二、实验要求
编写程序实现对5个进程的调度模拟,要求至少采用两种不同的调度算法分别进行模拟调度。
三、实验方法内容
1.算法设计思路
将每个进程抽象成一个控制块PCB,PCB用一个结构体描述。
构建一个进程调度类。将进程调度的各种算法分装在一个类中。类中存在三个容器,一个保存正在或未进入就绪队列的进程,一个保存就绪的进程,另一个保存已完成的进程。还有一个PCB实例。主要保存正在运行的进程。类中其他方法都是围绕这三个容器可以这个运行中的PCB展开。
主要用到的技术是STL中的vector以维护和保存进程容器、就绪容器、完成容器。
当程序启动时,用户可以选择不同的调度算法。然后用户从控制台输入各个进程的信息,这些信息保存到进程容器中。进程信息输入完毕后,就开始了进程调度,每调度一次判断就绪队列是否为空,若为空则系统时间加一个时间片。判断进程容器中是否有新的进程可以加入就绪队列。2.算法流程图 主程序的框架:
开始void FCFS();//先来先服务void SJF();//最短进程优先调度void RR();//简单时间片轮转void PD();//最高优先数优先void PCBInput();//输入进程信息选择调度算法输入进程信息将输入容器中以满足进入条件的进程调入就绪队列void ProcessQueueProcess();//查看当前时间下,有无进程加入。若有则把该进程调入就绪队列按照选择的算法开始选择就绪队列的进程开始执行void ProcessSelect();//若当前就绪队列不为空则根据选择的调度算法开始调度,否则,系统时间加一个时间片.以等待新的进程到判断就绪容器和输入容器是否为空!processScheduler.m_WaitQueue.empty()||!processScheduler.m_ProcessQueue.empt()Y打印各进程信息进行统计计算周转时间等结束void PCBDisplay();//打印当前状况下。就绪队列、完成队列、运行中的进程信息void SchedulerStatistics();//调度统计,计算周转时间等进程调度过程:
开始为空判断就绪队列是否为空if(m_WaitQueue.empty())非空让系统等待一个时间片TimePast()根据设定的调度算法从就绪队列中调入一个进程并执行(此时进程从就绪队列中删除,赋值到表示运行中的成员变量中)void FCFS();//先来先服务void SJF();//最短进程优先调度void RR();//简单时间片轮转void PD();//最高优先数优先进程运行一个时间片N是否达到该进程停止运行的条件Y选入的进程状态是否为“完成”如进程已完成,或者分得的时间片个数已到ProcessRun()Yvector
m_WaitQueue;//进程就绪队列进程未完成,将进程优先数减一,并放回到就绪队列中设置进程完成时间,将该进程放入完成队列vector
m_FinishQueue;//完成队列结束
3.算法中用到的数据结构
struct fcfs{
//先来先服务算法从这里开始
char name[10];
float arrivetime;
float servicetime;
float starttime;
float finishtime;
float zztime;
float dqzztime;
};
//定义一个结构体,里面包含的有一个进程相关的信息
4.主要的常量变量
vector
m_ProcessQueue;//进程输入队列
vector
m_WaitQueue;//进程就绪队列 vector
m_FinishQueue;//完成队列 vector
::iterator m_iter;//迭代器 PCB m_runProcess;//运行中的进程
int m_ProcessCount;//进程数 float m_RunTime;//运行时间
int m_tagIsRun;//是否在运行标志。表示正在运行,表示没有 float m_TimeSlice;//时间片大小
int m_TimeSliceCount;//指时间片轮转中一次分到的时间片个数 char m_SchedulerAlgorithm;//调度算法
5.主要模块
void PCBInput();//输入进程信息
void PCBSort();//对进程控制块按照优先级排序(采用冒泡排序)void ProcessSelect();//若当前就绪队列不为空则根据选择的调度算法开始调度。否则,系统时间void PCBDisplay();//打印当前状况下。就绪队列、完成队列、运行中的进程信息
void ProcessRun();//进程运行一次。运行时间加个时间片。并判断进程是否达到完成条件。若是则void ProcessQueueProcess();//查看当前时间下,有无进程加入。若有则把该进程调入就绪队列 void ProcessDispatch();//进程分派,进程执行完成后决定进程该进入哪个队列(就绪、完成)void TimePast(){ m_RunTime +=m_TimeSlice;ProcessQueueProcess();}//当前系统时间加个时间void SchedulerStatistics();//调度统计,计算周转时间等 void FCFS();//先来先服务 void SJF();//最短进程优先调度 void RR();//简单时间片轮转 void PD();//最高优先数优先 加.以等待新的进程到来
ProcessStatus='f'.否则为'w';片,并检查是否有新的进程加入
四、实验代码
#include
using namespace std;
struct fcfs{
//先来先服务算法从这里开始
char name[10];
float arrivetime;
float servicetime;
float starttime;
float finishtime;
float zztime;
float dqzztime;
};
//定义一个结构体,里面包含的有一个进程相关的信息
fcfs a[100];
void input(fcfs *p,int N)
{
int i;
cout< printf(“ 请您输入进程的名字 到达时间 服务时间:(例如: a 0 100)nn”); for(i=0;i<=N-1;i++) { printf(“ 请您输入进程%d的信息:t”,i+1); scanf(“ttt%s%f%f”,&p[i].name,&p[i].arrivetime,&p[i].servicetime); } } void Print(fcfs *p,float arrivetime,float servicetime,float starttime,float finishtime,float zztime,float dqzztime,int N) { int k; printf(“nn调用先来先服务算法以后进程运行的顺序是: ”); printf(“%s”,p[0].name); for(k=1;k { printf(“-->%s”,p[k].name); } cout< printf(“n 具体进程调度信息:n”); printf(“t进程名 到达时间 服务时间 开始时间 结束时间 周转时间 带权周转时间n”); for(k=0;k<=N-1;k++) { printf(“t%st%-.2ft %-.2ft %-.2ft %-.2ft %-.2ft %-.2fn”,p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime,p[k].zztime,p[k].dqzztime); } getchar(); //此处必须要有这个函数,否则就看不到显示器上面的输出,可以看到的结果只是一闪而过的一个框剪 } void sort(fcfs *p,int N)//排序 { for(int i=0;i<=N-1;i++) for(int j=0;j<=i;j++) if(p[i].arrivetime { fcfs temp; temp=p[i]; p[i]=p[j]; p[j]=temp; } } void deal(fcfs *p, float arrivetime,float servicetime,float starttime,float finishtime,float &zztime,float &dqzztime,int N) //运行阶段 { int k; for(k=0;k<=N-1;k++) { if(k==0) { p[k].starttime=p[k].arrivetime; p[k].finishtime=p[k].arrivetime+p[k].servicetime;} else { p[k].starttime=p[k-1].finishtime; p[k].finishtime=p[k-1].finishtime+p[k].servicetime;} } for(k=0;k<=N-1;k++) { p[k].zztime=p[k].finishtime-p[k].arrivetime; p[k].dqzztime=p[k].zztime/p[k].servicetime; } } void FCFS(fcfs *p,int N) { float arrivetime=0,servicetime=0,starttime=0,finishtime=0,zztime=0,dqzztime=0; sort(p,N); deal(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N); Print(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N); getchar(); } //先来先服务算法到此结束 struct sjf{//最短进程优先调度算法从这里开始 char name[10];float arrivetime;//到达时间 float servicetime;//运行时间 float starttime; //开始时间 float finishtime; //完成时间 };sjf a1[100]; void input(sjf *p,int N1)//进程信息输入 { int i;cout< printf(“ 请您输入进程的名字 到达时间 服务时间:(例如: a 0 100)n”); for(i=0;i<=N1-1;i++){ printf(“ 请您输入进程%d的信息:t”,i+1); scanf(“ttt%s%f%f”,&p[i].name,&p[i].arrivetime,&p[i].servicetime);} } void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,int N1)//最终结果输出 { int k; printf(“nt调用最短进程优先调度算法以后进程的调度顺序为:”); printf(“%s”,p[0].name); for(k=1;k {printf(“-->%s”,p[k].name);} cout< printf(“n给个进程具体调度信息如下:n”); printf(“nt进程名t到达时间t运行时间t开始时间t完成时间n”); for(k=0;k<=N1-1;k++) { printf(“ t%st %-.2ftt %-.2ftt %-.2ftt %-.2ftn”,p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime); } getchar(); } void sort(sjf *p,int N1)//排序 { for(int i=0;i<=N1-1;i++) for(int j=0;j<=i;j++) if(p[i].arrivetime { sjf temp; temp=p[i]; p[i]=p[j]; p[j]=temp; } } void deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,int N1)//运行阶段 { int k; for(k=0;k<=N1-1;k++) { if(k==0) { p[k].starttime=p[k].arrivetime; p[k].finishtime=p[k].arrivetime+float(p[k].servicetime)/60;} else { p[k].starttime=p[k-1].finishtime; p[k].finishtime=p[k-1].finishtime+float(p[k].servicetime)/60;} } } void sjff(sjf *p,int N1){ float arrivetime=0,servicetime=0,starttime=0,finishtime=0; sort(p,N1); for(int m=0;m {if(m==0) p[m].finishtime=p[m].arrivetime+float(p[m].servicetime)/60; else p[m].finishtime=p[m-1].finishtime+float(p[m].servicetime)/60; int i=0; for(int n=m+1;n<=N1-1;n++) { if(p[n].arrivetime<=p[m].finishtime) i++; } float min=p[m+1].servicetime; int next=m+1; for(int k=m+1;k { if(p[k+1].servicetime {min=p[k+1].servicetime; next=k+1;} } sjf temp; temp=p[m+1]; p[m+1]=p[next]; p[next]=temp; } deal(p,arrivetime,servicetime,starttime,finishtime,N1); Print(p,arrivetime,servicetime,starttime,finishtime,N1); getchar();}//最短进程优先调度算法到这里结束 char menu()//用来输出相关信息的函数 { char cse1; while(1) { system(“cls”); fflush(stdin); cout< cout< cout<<“t”<<“|| <<<<<<<<<<<<欢<<<<<<<<<<< >>>>>>>>>>>>迎>>>>>>>>>>> ||”< cout<<“t”<<“|| ||”< cout<<“t”<<“||”<<“t 进程调度算法模拟”<<“tt”<<“||”< cout<<“t”<<“|| ||”< cout<<“t”<<“||”<<“tt 1.先来先服务调度算法 ”<<“tt”<<“||”< cout<<“t”<<“|| ||”< cout<<“t”<<“||”<<“tt 2.最短进程优先调度算法”<<“tt”<<“||”< cout<<“t”<<“|| ||”< cout<<“t”<<“|| <<<<<<<<<<<<<<<<<<<<<<<<<您>>>>>>>>>>>>>>>>>>>>>>>>> ||”< cout< cout< cout<<“tt 请输入您的选择(1/2):”; cse1=getchar(); if(cse1<'1'||cse1>'2') cout<<“你的输入有错!”< else break; } return cse1;} int main(int argc, char *argv[]){ while(1) { switch(menu()) { case '1': int N; cout< cout< printf(“tt<<---!!@@@先来先服务调度算法@@@!!--->>n”); cout< printf(“输入进程数目:”); scanf(“%d”,&N); input(a,N); FCFS(a,N); case '2': int N1; cout< cout< printf(“tt<<---!!@@@最短进程优先调度算法@@@!!--->>n”); cout< printf(“输入进程数目: ”); scanf(“%d”,&N1); input(a1,N1); sjf *b=a1; sjf *c=a1; sjff(b,N1); getchar(); } } system(“PAUSE”); return EXIT_SUCCESS;} 五、实验结果 1.执行结果 2.结果分析 先来先服务调度算法就是根据进程达到的时间为依据,哪一个进程先来那么该进程就会先执行;最短进程优先调度算法则是以每个进程执行所需时间长短为依据,某一个进程执行所需花的时间要短些那么该进程就先执行。以上就是本次进程调度实验的依据。 六、实验总结 通过本次实验了解到算法很重要,又更加明白算法本身可以节约时间,而且不同的函数之间在调用的时候要注意很多的问题。 实验四 页面置换算法 一、实验目的 本实验主要对操作系统中请求分页式内存管理及其应用的一些关键算法进行模拟。学生通过设计与实现Clock算法,能够加强对相应理论的理解,并对了解操作系统内部的基本处理原理与过程也有很多益处。 二、实验要求 基本要求:描述Clock算法的基本原理、必要的数据结构、算法执行流程图、编码实现。 1)初始化:输入作业可占用的总页框数,初始化置空。 2)输入请求序列:输入一个作业页号访问请求序列,依次占用相应页框,直至全部占用; 3)Clock算法:当页框全部占用后,对于后续新的页号访问请求,执行Clock算法,淘汰1个页面后装入新的页号。 4)显示当前分配淘汰序列:显示淘汰的页号序列。 描述Clock算法的基本原理、必要的数据结构、算法执行流程图、编码实现。 三、实验内容 1)基本原理 时钟页面置换算法是把所有的页面都保存在一个类似钟面的环形链表中,一个表针指向最老的页面,如图所示。 当发生缺页中断时,算法首先检查表针指向的页面,如果它的R位是0就淘汰该页面,并把新的页面插入这个位置,然后把表针前移一个位置;如果R位是1就清除R位并把表针前移一个位置,重复这个过程直到找到了一个R位为0的页面为止。2)算法流程设计 主函数流程: STEP1:输入分配的页框数,页面访问次数和要访问的页面号序列 STEP2:内存页面初始化。内存中页面的数据结构为单循环链表,含有页号值yehao和访问位值a。开始时页号均为-1,访问位为0.STEP3:测试数据。具体算法是依要访问的页面号,调用find()函数查找是否已经存在于内存中。若存在,则修改其访问位为1.若不存在,触发缺页中断,调用tihuan()函数。最后,打印当前内存状态。如此循环直至测试串都访问完毕。3)主要函数实现 a)Makenode(double)函数:用于初始化一个节点。 b)Find(double)函数:依据输入的页号,查询内存中是否已存在此页面。若存在返回值1,不存在返回值0.c)Tihuan(double)函数:在发生缺页中断时,时钟指针查找访问位为0的页面进行替换,指针扫过的页面访问位置0,新加入的页面访问位置1。替换后指针下移。 d)Print_state()函数:打印当前内存中存在的页面的状态以及当前时钟指针所指向的页面位置。 4)测试数据 输入: 输入分配的页框数 3 输入页面访问次数 15 输入要访问的页面号序列 3 4 2 6 4 3 7 4 3 6 3 4 8 4 6 输出(仅最后一项): 5)结果分析 以下是clock算法对应输入页面号序列3 4 2 6 4 3 7 4 3 6 3 4 8 4 6的分析表 四、实验总结 1.加深对clock算法的理解。通过与其他算法的比较,我也了解了他们的异同之处。Clock算法其实是一种改进的第二次机会算法,它通过设置访问位,找到最早最不常访问的页面,即标号为0的页面。之所以叫clock算法,依我理解是将内存中的排列顺序附上时间的概念,clock指针扫过的页面要将他们1置0就是基于这个思想,因为他们都是没被访问的,且在时钟上的排列按照访问时间顺序。这样就保证了每次替换的都是最早进来的且不最常访问的页面。 2.在时钟内存结构的代码实现上,我使用了自建的单循环链表,对其进行顺序地遍历即可实现时钟指针的移动。另外通过全局变量node *r(时钟)node *start(开始页面项)node *r_prev(时钟指针的前驱)的设置,方便了有关算法的实现。 3.此算法较为简单,还有一种改进版的clock算法,增加了一个修改位,表示页框是否被修改过。这样的设计更加符合现在操作系统的调度原则。 参考文献 [1](美)Stanley B.Lippman 等 著 李师贤 等 译.C++ Primer中文版(第4版).人民邮电出版社, 2006-03-01 [2] 蒋爱军,李师贤,梅晓勇 著.C++ Primer习题解答(第4版).人民邮电出版社, 2007-02-01 [3] 塔嫩鲍姆(Tanenbaum.A.S),陈向群,马洪兵 著.现代操作系统(原书第3版).机械工业出版社, 2009-07-01 [4] 张尧学,史美林,张高.计算机操作系统教程.清华大学出版社, 2006-10-01 [5] 王晓东 著.数据结构(STL框架).清华大学出版社, 2009-09-01 实验四 死锁 一、实验目的 当系统的总资源数m小于或等于所有进程对对资源的最大需求时,就可能产生 死锁。死锁会引起计算机系统的瘫痪。银行家算法是在实现资源分配时避免死锁的一个著名算法,该算法是在能确保系统处于安全状态时才把资源分配给申请者。通过本实验使学生能进一步理解死锁的概念,并能选择一个算法来避免死锁。 二、实验题目 系统中有m个同类资源被n个进程共享,每个进程对资源的最大需求数分别为S1, S2,…,Sn,且 Max(Si)<=m,(i=1,2,…n)。进程可以动态地申请资源和释放资源。编写一个程序,现银行家算法,当系统将资源分配给某一进程而不会死锁时,就分配之。否则,推迟分配,并显示适当的信息。 三、数据结构 主要数据结构: Struct aa { void Print();//用于打印输出表格的函数 void Input();//用于输入的函数 void tryfenpei(int i);//试分配函数 void refenpei(int i);//恢复数据函数 void checksafe(int s);//安全检测函数 }; 四、银行家算法的流程图 开始初始化资源类数c=3,进程数t=5初始化Available[c],Max[t][c],Allocation[t][c],Need[t][c],Request[c]输入进程数iInt f=0f 五、源代码 #include void Print();//用于打印输出表格的函数 void Input();//用于输入的函数 void tryfenpei(int i);//试分配函数 void refenpei(int i);//恢复数据函数 void checksafe(int s);//安全检测函数 //定义初始化数组 int Available[c], Max[t][c], Allocation[t][c], Need[t][c], Request[c]; int in;//用户选择的进程号 int main(int argc, char *argv[]){ int i;char ch='Y';cout<<“初始化数据如下:”< cout<<“试分配完成!”< cout<<“需要继续实验吗?(y-继续 n终止)”;} else if(ch=='N'||ch=='n'){ cout<<“感谢您的使用,祝您愉快!”< void Print(){ int i,j;cout<<“ 进程个数 : ”< void Input(){ for(int j=0;j { for(int m=0;m void tryfenpei(int i){ for(int f=0;f //安全检测函数 void checksafe(int s){ int Work, flag, temp[t], i,j,l=0,k=0;bool Finish[t];for(i=0;i } if(l==5)//一共有三类资源A B C,一条进程下面的安全性检测只检测了A类。如果A类通过了,那么还要判断B类,C类。否则不用 { for(i=0;i } i=s;//s传递进来赋给i,s是用户输入的进程号(有主函数里的in传递进来)while(i if(Finish[i]==false&&Need[i][j]<=Work){ Work=Work+Allocation[i][j];Finish[i]=true;temp[k]=i;//cout<<“temp=”< 六、执行结果: 七、实验总结 通过本次实验了解到用银行家算法来预防死锁是可靠的,但也是非常保守的,因为它限制了进程对资源的存取,从而降低了进程的并发运行程度。死锁检测并不限制进程对资源的申请,只要有,就分配,但这也可能造成死锁。但由于死锁并不是经常发生的,故大大提高了系统运行的效率。 总之,通过本实验,使我进一步加深理解和掌握银行家算法。 天津大学仁爱学院 实验类型:实验名称:实验地点: 学生姓名:班 级: 操作系统 实验报告 必 修 实验日期:2014年4月18日进程调度 二实验楼504 李帅帅 指导教师:张 磊 计科一班 计算机科学与技术系 天津大学仁爱学院——计算机科学与技术系——李帅帅 实验报告内容: 1)实验目的 用c语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。 2)实验器材和设备 硬 件: 二实验楼504计算机 开发工具: Microsoft Visual C++ 6.0 3)实验任务 本实验模拟单处理器系统的进程调度,加深对进程的概念及进程调度算法的理解。用c语言编写和调试一个进程调度的算法程序,有一些简单的界面,能够运行,仿真操作系统中进程调度的原理和过程。通过对调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度 4)实验原理 无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。 基本状态:1.等待态:等待某个事件的完成; 2.就绪态:等待系统分配处理器以便运行; 3.运行态:占有处理器正在运行。 运行态→等待态 往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的。 等待态→就绪态 则是等待的条件已满足,只需分配到处理器后就能运行。运行态→就绪态 不是由于自身原因,而是由外界原因使运行状态的进程让出处理器,这时候就变成就绪态。例如时间片用完,或有更高优先级的进程来抢占处理器等。 就绪态→运行态 系统按某种策略选中就绪队列中的一个进程占用处理器,此时就变成了运行态 5)实验过程描述 a)打开Microsoft Visual C++ 6.0,创建工程。 b)根据要求用 c语言代码实现应用程序,并调试完成。c)运行程序,根据提示输入相应的字符。 d)输入实验测试内容,并观察执行窗口显示的过程。 天津大学仁爱学院——计算机科学与技术系——李帅帅 q=(struct pcb *)malloc(sizeof(pcb)); cin>>q->name; cin>>q->needtime; q->cputime=0; q->priority=P_TIME-q->needtime; q->process=ready; q->next=NULL; if(i==0) { p=q; t->next=q; } else { q->next=t->next; t=q; q=p; } i++;} return p;} void display(pcb * p){ cout<<“name”<<“ ”<<“cputime”<<“needtime”<<“ ”<<“priority”<<“ ” <<“state”< cout< name; cout<<“ ”; cout< cputime; cout<<“ ”; cout< needtime; cout<<“ ”; cout< priority; cout<<“ ”; switch(p->process) { case ready:cout<<“ready”< case execute:cout<<“execute”< case block:cout<<“block”< case finish:cout<<“finish”< } 天津大学仁爱学院——计算机科学与技术系——李帅帅 void priority_cal(){ pcb * p;system(“cls”);p=get_process();int cpu=0;system(“cls”);while(!process_finish(p)){ cpu++; cout<<“cuptime:”< cpuexe(p); display(p); Sleep(1000);} printf(“All processes have finished,press any key to exit”);getch();} void display_menu(){ cout<<“nCHOOSE THE ALGORITHM:”< pcb *get_process_round(){ pcb *q;pcb *t;pcb *p;int i=0;t=(struct pcb *)malloc(sizeof(pcb));p=(struct pcb *)malloc(sizeof(pcb));cout<<“input name and time”< cin>>q->name; cin>>q->needtime; q->cputime=0; 天津大学仁爱学院——计算机科学与技术系——李帅帅 { } } return t;} void set_state(pcb *p){ while(p){ if(p->needtime==0) { p->process=finish;//如果所需执行时间为0,则设置运行状态为结束 } if(p->process==execute) { p->process=ready;//如果未执行状态则设置为就绪 } p->next;} }//设置队列中进程执行状态 void display_round(pcb *p){ cout<<“NAME”<<“ ”<<“CPUTIME”<<“ ”<<“NEEDTIME”<<“ ”<<“COUNT”<<“ ”<<“ROUND” <<“ ”<<“STATE”< cout< name; cout<<“ ”; cout< cputime; cout<<“ ”; cout< needtime; cout<<“ ”; cout< count; cout<<“ ”; cout< round; cout<<“ ”; switch(p->process) { case ready:cout<<“ready”< case execute:cout<<“execute”< case finish:cout<<“finish”< 天津大学仁爱学院——计算机科学与技术系——李帅帅 7)实验结果截图 1.实验题目: 磁盘调度算法。 建立相应的数据结构; 在屏幕上显示磁盘请求的服务状况; 将一批磁盘请求的情况存磁盘文件,以后可以读出并重放; 计算磁头移动的总距离及平均移动距离; 支持算法:FIFO、SSTF、SCAN、CSCAN; 2.设计目的: 调度磁盘I/O请求服务,采用好的方式能提高访问时间和带宽。本实验通过编程对磁盘调度算法的实现,加深对算法的理解,同时通过用C++语言编写程序实现这些算法,并在windos平台上实现,更好的掌握操作系统的原理以及实现方法,提高综合运用专业课知识的能力。 3.任务及要求 3.1 设计任务 编程实现下述磁盘调度算法,并求出每种算法的平均寻道长度: 1、先来先服务算法(FCFS) 2、最短寻道时间算法(SSTF) 3、扫描算法(SCAN) 4、循环扫描算法(CSCAN) 3.2 设计要求 对用户指定的磁盘调度请求序列,基于以上四种算法,实现各自的调度顺序并输出,同时计算出各种算法下的平均寻道长度。 4.算法及数据结构 4.1算法的总体思想 queue[n] 为请求调度序列,diskrode为磁盘磁道数,headstarts为正在调度的磁道 ①先来先服务算法(FCFS)按queue[n]数组的顺序进行磁盘调度,将前一个调度磁道与下一个调度磁道的差值累加起来,得到总的寻道长度,再除以n得到平均寻道长度。 ②最短寻道时间优先算法(SSTF)将queue[n]进行由小到大的排序,首先定位当前调度磁headstarts在queue[n]的位置,通过循环语句找出离起始磁头最短的位置。 ③扫描算法(SCAN) 将queue[n]进行由小到大的排序,首先定位当前调度磁headstarts在queue[n]的位置,然后在此位置按给定的方向遍历queue[n],当道端点(queue[0]或queue[n-1])时,再在定位处反向遍历到另一端。当调度磁道不在queue端点时,总的寻道长度为为前一个磁道与后一个磁 道差值的累加,当到达端点且queue[n]未全调度时,总寻道长度加上端点值再加上下一个调度磁道的值,再按前面的算法进行,直到磁道全部都调度完毕,得到总的寻道长度,除以n得到平均寻道长度。 ④循环扫描算法(CSCAN)将queue[n]进行由小到大的排序,首先定位当前调度磁headstarts在queue[n]的位置,然后在此位置按给定的方向遍历queue[n],当道端点(queue[0]或queue[n-1])时,反向到另一端点再以此方向进行遍历,直到queue[n]中所有都调度完。当调度磁道不在queue端点时,总的寻道长度为为前一个磁道与后一个磁道差值的累加,当到达端点且queue[n]未全调度时,总寻道长度加上端点值再加上磁盘磁道总长度,再加上下一个调度磁道的值,再按前面的算法进行,直到磁道全部都调度完毕,得到总的寻道长度,除以n得到平均寻道长度。 5、源代码: #include 1、先来先服务算法(FCFS)**********”< cout<<“****** 2、最短寻道时间优先算法(SSTF)**********”< cout<<“****** 3、扫描算法(SCAN)**********”< cout<<“****** 4、循环扫描算法(CSCAN)**********”< cout<<“****** 5、退出 **********”< /*======================初始化序列=======================*/ void init(int queue[],int queue_copy[],int n){ int i;for(i=0;i //对当前正在执行的磁道号进行定位,返回磁道号小于当前磁道中最大的一个 int fix(int queue[], int n, int headstarts){ int i =0;while(i /* ====================以下是FCFS算法==================*/ void FCFS(int queue[],int n,int diskrode,int headstarts)//queue是请求调度序列,n为其个数,diskroad为磁盘磁道数,headstarts为正在调度的磁道 { cout<<“************以下为FCFS调度算法***********”< /*=====================SSTF算法====================*/ void SSTF(int queue[], int n, int diskrode, int headstarts){ int k=1;int l,r;int i,j,count=0;queue =bubble(queue,n);cout<<“************以下为SSTF调度算法***********”< -headstarts)){ cout< /*======================以下是SCAN算法====================*/ void SCAN(int queue[], int n, int diskrode, int headstarts){ int direction, i, fixi;cout<<“***********以下是SCAN调度算法*************”< /*======================以下是CSCAN算法====================*/ void CSCAN(int queue[],int n,int diskrode,int headstarts){ int direction,i,fixi;cout<<“***********以下是CSCAN调度算法*************”< void main(){ int n, i, diskrode, headstarts;//n表示调度磁盘请求序列queue的长度,diskrode表示磁盘磁道的个数,headstarts表示目前正在调度的磁道; cout<<“请输入磁盘的总磁道数:”< if(menux ==2)SSTF(queue,n,diskrode,headstarts); if(menux ==3)SCAN(queue,n,diskrode,headstarts);if(menux ==4)CSCAN(queue,n,diskrode,headstarts);if(menux ==5)cout<<“程序结束,谢谢使用!”<第二篇:操作系统实验报告(clock算法)
第三篇:操作系统银行家算法实验报告
第四篇:进程调度实验报告
第五篇:操作系统课程设计-磁盘调度算法