第一篇:常用进程调度算法的分析与评价
常用进程调度算法的分析与评价
(一)2009-10-31 22:48
进程调度是按照某种调度算法从就绪状态的进程中选择一个进程到处理机上运行。进程调度的两种方式 :
(1)非抢占调度方式
在这种调度方式中,OS一旦把处理机分配给某个就绪状态的进程后,就让该进程一直执行下去,直至该进程完成或由于该进程等待某事件发生而被阻塞时,才把处理机分配给其他进程。
(2)抢占调度方式
在这种调度方式中,进程调度程序可根据某种原则停止正在执行的进程,将已分配给当前进程的处理机收回,重新分配给另一个处于就绪状态的进程。
抢占进程调度的原则:
(1)时间片原则:各进程按系统分配给的一个时间片运行,当该时间片用完或由于该进程等待某事件发生而被阻塞时,系统就停止该进程的执行而重新进行调度。
(2)优先级原则:每个进程均赋于一个调度优先级,通常一些重要和紧急的进程赋于较高的优先级。当一个新的紧迫进程到达时,或者一个优先级高的进程从阻塞状态变成就绪状态的时,如果该进程的优先级比当前进程的优先级高,OS就停止当前进程的执行,将处理机分配给该优先级高的进程,使之执行。
(3)短进程优先原则:当新到达的作业对应的进程比正在执行的作业对应进程的运行时间明显短时,系统剥夺当前进程的执行,而将处理机分配给新的短进程,使之优先执行。进程调度算法评价依据
进程调度性能的衡量方法可以分为定性和定量两种,在定性衡量方面,首先是调度的安全性。比如,一次进程调度是否可能引起数据结构的破坏等。这要求对调度时机的选择和保存CPU现场十分小心。另外,系统开销也是衡量进程调度的一个重要指标,由于调度程序的执行涉及到多个进程的上下文切换,如果调度策略过于繁琐和复杂,将会耗去较大的系统开销。这在用户进程调度系统调用较多的情况下,将会造成响应时间大幅度增加。
进程调度的定量评价包括CPU的利用率评价、进程在就绪队列中的等待时间与执行时间之比等。实际上,由于进程进入就绪队列的随机模型很难确定,而且进程上下文切换等也将影响进程的执行效率,从而对进程调度进行解析是很困难的,一般情况下,大多利用模拟或测试系统响应时间的方法来评价进程调度的性能。
常用进程调度算法的分析与评价
(二)2009-11-01 20:22
四种常用进程调度算法的分析与评价
3.1 先来先服务算法
3.1.1 算法思想
该算法思想是按照进入就绪队列的先后次序来分配处理机。FCFS采用非剥夺调度方式,即
一旦某个进程占有处理机,就一直运行下去,直到该进程完成其工作或因等待某一事件而不能继续执行时才释放处理机。
3.1.2 算法实现原理图
该算法实现原理图如图1所示。
说明:Ready表示就绪队列,Pi表示新进入队列的进程,Finish表示进程运行完毕退出。
3.1.3 算法分析与评价
① 该算法原理简单,易于实现。
② 各进程平等竞争。
③ 由于各进程执行的时间不一样,从而导致相对不公平现象的产生。
④ 该算法有利于长进程,不利于短进程。
⑤ 该算法很少用来作为主调度策略,常常用作辅助调度算法使用
3.2最高优先权优先调度算法
3.2.1 算法思想
该算法的基本思想是进程优先权高者优先调度,是一种最常用的进程调度算法。该算法的关键是如何确定优先数。通常确定优先数的方法有两种,即静态法和动态法。
静态优先权是在创建进程时确定的,其运行特征是优先数确定之后在整个进行运行期间不再改变。确定静态优先权的依据有进程的类型、进程所使用的资源、进程的估计运行时间等因素。进程所申请的资源越多,估计的运行时间越长,进程的优先权越低。进程类型不同,优先权也不同,如系统进程的优先权高于用户进程的优先权。
动态优先权是指在创建进程时,其运行特征是根据系统资源的使用情况和进程的当前特点确定一个优先权,在进程运行过程中再根据情况的变化调整优先权。动态优先权一般根据进程占有CPU时间的长短、进程等待CPU时间的长短等因素确定。占有处理机的时间越长,则优先权越低;等待时间越长,则优先权越高。
3.3.2 算法分析与评价
① 静态优先级调度算法实现较为简单,但不能反映系统以及进程在运行过程中发生的各种变化。而动态优先级法可以满足这个方面的需要。
② 动态优先级调度算法的性能一般介于时间片轮转算法和先来先服务算法之间。
常用进程调度算法的分析与评价
(三)2009-11-01 20:23
3.3时间片轮转调度算法
3.3.1 算法思想
该算法思想是使每个进程在就绪队列中的等待时间与享受服务的时间成比例。即将CPU的处理时间分成固定大小的时间片,如果在执行的一个进程把它分给它的时间片用完了,但任务还没有完成,则它也只能停止下来,释放它所占的CPU资源,然后排在相应的就绪队列的后面去。
3.3.2 算法实现原理图
该算法实现原理图如图2所示
说明:Ready表示就绪队列,Pi表示新进入队列的进程,Finish表示进程运行完毕退出。Not Finish表示分配给某进程的时间片已用完但任务还没有完成,从而插入到Ready队列尾部。
3.3.3 算法分析与评价
① 时间片的长度选择比较困难
时间片的长度选择比较困难是因为时间片长度的选择直接关系到系统开销和进程的响应时间。如果时间片长度过短→导致调度程序剥夺处理器的次数增加→进程的上下文切换的次数增加→系统的开销也加重;如果时间片长度过长,长到能使就绪队列中所需要执行时间最长的进程执行完
毕→轮转法就变成了FCFS算法→FCFS短处不足就显示出来了。
又因为CPU的整个执行时间=各进程执行时间之和+系统开销(各进程切换所花费的CPU时间之和,假定存储开销忽略不计)。即。因此,时间片的长短通常需要由以下因素确定:↙系统的响应时间。
↙就绪队列中的进程数。
↙进程的切换时间。
↙ 计算机的处理能力,计算机的速度越高,时间片就可越短。
② 时间片长度选择的动态性
以上仅仅作了静态分析,通常情况下,就绪队列里地进程个数是不断变化的。因此,每一次的调度都需要计算新一轮的时间片长度,不能用固定的时间片长度来进行所有进程的轮转执行。③ 该算法的扩充——多级反馈轮转法
在上面的算法中,未对就绪队列中的进程加以条件分析(即进入就绪队列的因素),由于进入就绪队列的原因不一样,要求占用处理机的紧急程度也不一样。主要因素有:↙分给该进程的时间片用完,但进程还未完成。
↙ 分给其时间片未用完,而发生了I/O等请求后由阻塞态转变成就绪态。
↙新的进程进入。
因此,根据紧急程度的不一样,建立多个就绪队列,同时赋予不同的的优先级,优先权高的就绪队列优先执行,同一就绪队列中,优先级相同,按照先来先服务进行调度,运行一个给定的时间片,如果没有执行完成则转入到相应的就绪队列中去(运行一次,优先级降低一个等级,等待一个时间片,则优先级升高一个等级)。其实现原理图如图3所示。
3.4 短进程优先调度算法
3.4.1 算法思想
该算法的基本思想是从就绪队列(内存)中选择一个估计运行时间最短的进程,将处理机分配给它。
3.4.2 算法分析与评价
① 该算法能有效降低作业的平均等待时间,提高系统吞吐量。
② 对长进程不利,甚至导致长期得不到处理。
③ 该算法完全未考虑进程的紧迫程度。
④ 进程的长短通常由某种策略估计提供,不能做到真正的短进程优先。
4结语
综述所述,本文从算法思想、算法的实现原理、算法的优缺点等几个方面对先来先服务算法、时间片轮转算法、最高优先权优先调度算法、短进程优先调度算法等四种进程调度算法进行详细地论述。(转自《计算机与信息技术》)
第二篇:操作系统进程调度算法模拟实验报告
进程调度算法模拟
专业: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.结果分析 先来先服务调度算法就是根据进程达到的时间为依据,哪一个进程先来那么该进程就会先执行;最短进程优先调度算法则是以每个进程执行所需时间长短为依据,某一个进程执行所需花的时间要短些那么该进程就先执行。以上就是本次进程调度实验的依据。 六、实验总结 通过本次实验了解到算法很重要,又更加明白算法本身可以节约时间,而且不同的函数之间在调用的时候要注意很多的问题。 操作系统课程设计 进 程 调 度 实 践 报 告 姓名: 董宇超 班级:计算机一班 学号:0906010124 目录: 实践内容 实践目的及意义 功能设计及数据结构 调试运行及测设分析 存在的问题及改进设想 实践体会 总结 参考文献 正文: 1.实践内容: 2.3.在多道程序运行环境下,进程数目一般多于处理机数目,使得进程要通过竞争来使用处理机。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之运行,分配处理机的任务是由进程调度程序完成的。一个进程被创建后,系统为了便于对进程进行管理,将系统中的所有进程按其状态,将其组织成不同的进程队列。于是系统中有运行进程队列、就绪队列和各种事件的进程等待队列。进程调度的功能就是从就绪队列中挑选一个 进程到处理机上运行。进程调度的算法有多种,常用的有先来先服务算法、时间片轮转算法。 采用先来先服务及时间片轮转算法进行进程调度,编程模拟。实践目的: ·要求设计并实现模拟进程调度的算法:时间片轮转及先来先服务。·理解进程控制块的结构。·理解进程运行的并发性。·掌握进程调度算法。功能设计: 1)数据结构: class PCB { string ProcessName;// 进程名字 int Time;// 进程需要时间 int LeftTime;// 进程运行一段时间后还需要的时间 } 2)功能函数: void Copy(Process proc1, Process proc2);// 把proc2赋值给proc1 void sort(Process pr[], int size);// 此排序后按需要的cpu 时间从小到大排列 void Fcfs(Process pr[], int num);// 先来先服务算法 void TimeTurn(Process process[], int num, int Timepice);// 时 间片轮转算法 源代码: #include }; void Copy(PCB proc1, PCB proc2);// 把proc2赋值给proc1 void sort(PCB pr[], int size);// 此排序后按需要的cpu时间从小到大排列 void Fcfs(PCB pr[], int num);// 先来先服务算法 void TimeTurn(PCB process[], int num, int Timepice);// 时间片轮转算法 void main(){ int a;cout< process[Size];int num;int TimePice; cout<<“输入进程个数:”< } for(int i=0;i< num;i++)//输入进程信息 { } for(int k=0;k cout< int LeftTime;// 进程运行一段时间后还需要的时间 } { } else if(a==2)//时间片轮转调度 { } cout<<“进程名”<<“ 剩余时间”<<“ 状态”< CPU时间 ”<<“ 状态”< } void sort(PCB pr[], int size)// 以进程时间从低到高排序 {// 直接插入排序 } /* 先来先服务算法的实现*/ void Fcfs(PCB process[], int num){ // process[] 是输入的进程,num是进程的数目 while(true){ if(num==0){ } if(process[0].LeftTime==0)//由于第一个进程总是在运行,所以每次都只判断process[0].LeftTime { cout<<“ 所有进程都已经执行完毕!”< } PCB temp;temp = pr[i];int j=i; while(j>0 && temp.Time < pr[j-1].Time){ } pr[j] = temp;pr[j] = pr[j-1];j--;proc1.ProcessName =proc2.ProcessName;proc1.Time =proc2.Time; } } cout<<“ 进程”< } else if(process[0].LeftTime > 0){ cout< 运行”;cout< for(int s=1;s } cout<<“ ”< “< 等待”< /* 时间片轮转调度算法实现*/ void TimeTurn(PCB process[], int num, int Timepice){ while(true){ if(num==0){ } if(process[0].LeftTime==0)//由于第一个进程总是在运行,所以每次都只判断process[0].LeftTime { cout<<“ 进程”< } } num--;if(process[num-1].LeftTime ==0){ } else if(process[0].LeftTime > 0){ cout< } PCB temp;//中间变量 temp = process[0];for(int j=0;j 等待”< 就绪”< process[0].LeftTime=process[0].LeftTime-Timepice;if(process[0].LeftTime<=0)//当剩余时间小于零时,做零处理 process[0].LeftTime=0;cout<<“ ”< “< 运行”< for(int s=1;s cout<<” 进程“ << process[num-1].ProcessName <<” 已经执行完毕!"< } // while 4.调试运行: 运行开始后出现如下界面: 按提示选择1/2; 先选1,进行FCFS调度: 若选2,进行时间片轮转调度: 5.存在的问题: 由于初次做操作系统模拟实验,所以程序设计中存在很多问题,例如定义好PCB后,各种指针的使用,使得程序甚是复杂,再加上队列指针,而且指针错误在调试的时候不提示错误,只是编好的程序看似没有错误,却在执行时出现异常而中断,由于使用指针使得程序庞大检查改正困难,无法发现隐藏的错误,只是程序无法进行下去。 最终本程序选择数组保存PCB信息,存储和调用都简单化。 改进之处:学习指针,并且使用三个队列,就绪队列,运行队列,完成队列,使得进程调度模拟更加清晰。 还有一些简单的以解决的问题,不一一列举了。 6.实践心得体会: 通过这次实践学会了不少内容,更深的理解了进程调度的几种算法,而且学 会了系统的编写程序,而不是只编写几个功能函数。在编程过程中,需要 查阅各种资料,并且学习前人的编写方法,找出优劣,然后形成自己的思想,最终完成程序的编写。 通过模拟进程调度的两种算法,懂得了各种算法在不同情况下的作用。选择 一个好的调度算法可以是计算机在执行庞大的作业时井井有条,并且使用时 间很短。 在模拟过程中出现过好多问题,有的解决了,有的还未解决,不管如何都是 一种收获,编写功能函数时总会出现参数调用错误的情况,通过分析解决了。在指针指向的问题上,觉得很复杂,最终没有解决。 7.总结: 为期一周的操作系统实践课结束了,编写了包含有两种调度算法的进程 调度模拟程序,两种程序各有优劣,FCFS调度算法是按照进程进入系统的时 间先后被CPU选择创建的,这种算法易于实现,但效率不高,只顾及到进程 的等候时间,没考虑要求服务的时间长短,相比SJF算法不利于较短的作业。本程序的另一种调度算法是RR算法,它在调度是是为每个进程分配时间片,当时间片用完时,进程便排到队尾以便下次分配,这种调度策略可以防止那 些很少使用设备的进程长时间占用处理器,导致要使用设备的那些进程没机 会启动设备。 在编写程序的同时,还学习了进程调度的其他算法,明白了它们各自的优劣,懂得了计算机在调度进程时的取舍。 8.参考文献: 1.操作系统教程(第4版)…………孙钟秀 主编 高等教育出版社; 2.算法与数据结构-C语言描述(第2版)……张乃孝 主编 高等教育出版社; 3.网络资源; 天津大学仁爱学院 实验类型:实验名称:实验地点: 学生姓名:班 级: 操作系统 实验报告 必 修 实验日期: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)实验结果截图 电梯优先调度算法 电梯调度算法(ms InterView) 移臂调度算法包括以下四种: 1)先来先服务算法:根据访问者提出访问请求的先后次序来决定执行次序。 2)最短寻找时间优先调度算法:从等待的访问者中挑选寻找时间最短的那个请求执行,而不管访问者的先后次序。 3)电梯调度扫描算法:从移动臂当前位置沿移动方向选择最近的那个柱面的访问者来执行,若该方向上无请求访问时,就改变移动方向再选择。 4)单向扫描调度算法:从0柱面开始往里单向扫描,扫到哪个执行哪个。 */ // t1.cpp : 定义控制台应用程序的入口点。 // #include “stdafx.h” #include“math.h” #include“stdlib.h” #include“string.h” struct Head { int nPosition;bool bVisited;}; void Visit(struct Head *pHead){ printf(“visite cy:%dn”,pHead->nPosition);pHead->bVisited=true;} int ReadInputKeyboard(struct Head *pHead,int *pCurrentPosition,int nMaxNumber){ int i; printf(“please input Current position:”);scanf(“%d”,pCurrentPosition); printf(“please input will visit position:”);for(i=0;i scanf(“%d”,&pHead[i].nPosition);pHead[i].bVisited=false;if(pHead[i].nPosition<0)break;} return i;} int ReadInputFile(struct Head *pHead,int *pCurrentPosition,int nMaxNumber){ int i; char szFileName[256],*q,*p,szTemp[20];printf(“please input filename:”);scanf(“%s”,szFileName); FILE *pFile=fopen(szFileName,“r”);if(pFile==NULL){ printf(“open file %s error”,szFileName);return-1;} for(i=0;!feof(pFile)&&i p=szFileName;fgets(p,256,pFile); while(q=strchr(p,',')){ memset(szTemp,0,sizeof(szTemp)*sizeof(char));strncpy(szTemp,p,q-p);p=q+1;if(i==0) *pCurrentPosition=atoi(szTemp);else { pHead[i-1].nPosition=atoi(szTemp);pHead[i-1].bVisited=false;} i++;} memset(szTemp,0,sizeof(szTemp)*sizeof(char));pHead[i-1].nPosition=atoi(p);pHead[i-1].bVisited=false;//i++; } fclose(pFile);return i;} int FifoVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ //先来先服务 int nHaveVisited=0;int nMoveDistance=0;int i;while(nHaveVisited for(i=0;i if(pHead[i].bVisited)continue; Visit(&pHead[i]);nHaveVisited++; nMoveDistance+=abs(nCurrentPosition-pHead[i].nPosition);nCurrentPosition=pHead[i].nPosition;} } printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int SsfoVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ // 最短寻找时间优先 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i; while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } //访问 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int DtVisit(int nCurrentPosition,bool bOut,struct Head *pHead,int nNumber){ //电梯调度算法 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i; while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(bOut&&pHead[i].nPosition if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } } if(nMinDistance==0xffff){ bOut=!bOut;continue;} //访问 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int DxVisit(int nCurrentPosition,struct Head *pHead,int nNumber){ //单向调度算法 int nHaveVisited=0;int nMoveDistance=0;int nMinDistance=0;int nMinIndex=0;int i;while(nHaveVisited nMinDistance=0xffff;nMinIndex=0;//找最小值 for(i=0;i if(pHead[i].bVisited)continue; if(pHead[i].nPosition>nCurrentPosition){ if(nMinDistance>abs(pHead[i].nPosition-nCurrentPosition)){ nMinDistance=abs(pHead[i].nPosition-nCurrentPosition);nMinIndex=i;} } } if(nMinDistance==0xffff){ nMoveDistance+=199-nCurrentPosition;nCurrentPosition=0;continue;} //访问 Visit(&pHead[nMinIndex]);nHaveVisited++; nMoveDistance+=nMinDistance; nCurrentPosition=pHead[nMinIndex].nPosition;} printf(“the sum of move distance:%dn”,nMoveDistance);return nMoveDistance;} int main(int argc, char* argv[]){ //p114 struct Head mylist[20];//={98,false,183,false,37,false,122,false,14,false,124,false,65,false,67,false}; //int nCurrentPosition=53; //int nRealNumber=8; int nCurrentPosition=0; int nRealNumber=ReadInputFile(mylist,&nCurrentPosition,20);// FifoVisit(nCurrentPosition,mylist,nRealNumber); // SsfoVisit(nCurrentPosition,mylist,nRealNumber); //DtVisit(nCurrentPosition,false,mylist,nRealNumber); DxVisit(nCurrentPosition,mylist,nRealNumber); return 0;}第三篇:进程调度
第四篇:进程调度实验报告
第五篇:电梯优先调度算法