当前位置:文档之家› 操作系统课程设计报告-进程调度算法模拟

操作系统课程设计报告-进程调度算法模拟

1.课程设计的目的《操作系统原理》课程设计我们专业实践性环节之一,是学习完《操作系统原理》课程后进行的一次较全面的综合练习。

其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。

2.课程设计的内容及要求先来先服务、短作业优先、时间片轮转、基于静态优先级的调度,基于高响应比优先的动态优先级调度算法实现,能够输出调度情况,并计算周转时间和平均周转时间。

要求使用链表,进程个数由用户提供,按照进程的实际个数生成PCB,程序能够让用户选择使用哪种调度算法,能够在Linux环境运行并验证结果。

程序要考虑用户界面的友好性和使用方便性。

进程基本信息可从文件读入,也可手动输入。

3、设计原理3.1先来先服务调度算法每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源创建进程,然后放入就绪队列3.2短作业优先调度算法短作业优先调度算法是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。

3.3时间片轮转调度算法系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。

时间片的大小从几ms到几百ms。

当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。

3.4静态优先级调度算法把处理机分配给优先级最高的进程,使之执行。

但在其执行期间,只要出现了另一个比其优先级更高的进程,调度程序就将处理机分配给新到的优先级最高的进程。

这样就可以保证紧迫性作业优先运行。

3.5最高响应比优先的动态优先级调度算法优先权调度算法是为了照顾紧迫型作业,使之在进入系统后便获得优先处理,引入最高优先权优先调度算法。

动态优先权是指在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。

4.设计说明4.1结构设计(1) 菜单选择模块。

选择相应的进程调度方式,选择相应的数字,进入相应的功能。

(2) 调度算法模块。

选择相应的进程调度算法。

(3) 显现输出模块。

显示每种进程调度算法情况。

(4) 平均周转时间与平均带权周转时间的计算结果。

(5) 退出系统模块。

4.2功能设计(1)菜单选择模块设计方案:首先将各种进程调度算法放入不同的头文件,在主函数引用,是系统结构更加清晰。

实现方法:设置一个menu()方法,让用户选择不同的进程调度算法,menu()方法返回一个char类型字符,以便在主函数的switch语句中选择调用不同的进程调度方法。

(2)调度算法模块A、先来先服务调度算法设计方案:对于先到达的进程优先分配CPU,按照先来先服务的原则依次执行各进程。

实现方法:每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源创建进程,然后放入就绪队列B、短作业优先调度算法设计方案:短作业优先调度算法是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。

实现方法:先找到运行时间最短的程序,然后执行,再从剩余的程序中找到运行时间最短的在执行,依次每次都执行运行时间最短的,直到程序执行完毕。

C、时间片轮转调度算法设计方案:系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。

时间片的大小从几ms到几百ms。

当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。

实现方法:按照轮转的次序分配给每个程序一定的时间执行,执行完成后执行后面的进程,依次循环执行直到所有进程执行完成。

D、静态优先级调度算法设计方案:把处理机分配给优先级最高的进程,使之执行。

但在其执行期间,只要出现了另一个比其优先级更高的进程,调度程序就将处理机分配给新到的优先级最高的进程。

这样就可以保证紧迫性作业优先运行。

实现方法:按照优先级从高到低依次执行程序。

E、最高响应比优先的动态优先级调度算法设计方案:优先权调度算法是为了照顾紧迫型作业,使之在进入系统后便获得优先处理,引入最高优先权优先调度算法。

动态优先权是指在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。

实现方法:按照优先级从高到低依次执行程序。

(3)平均周转时间与平均带权周转时间的计算设计方案:周转时间=完成时间-到达时间带权周转时间=周转时间/服务时间平均周转时间=总的周转时间/进程个数平均带权周转时间=总的带权周转时间/进程个数实现方法:系统自行根据程序及输入的数据计算出平均周转时间和平均带权周转时4.3程序中使用的数据结构及使用的变量说明和作用(1)结构体/***先来先服务调度算法结构体***/struct fcfs{char name[10]; //作业名float arrivetime; //作业到达时间float servicetime; //作业服务时间float starttime; //作业开始时间float finishtime; //作业完成时间float zztime; //周转时间float dqzztime; //带权周转时间};/***短作业优先调度算法结构体***/struct jcb //作业控制块JCB,定义为结构体{char name[10]; //作业名float arrivetime; //作业到达时间float servicetime;//作业服务时间float finishtime; //作业完成时间float zztime; //周转时间float dqzztime; //带权周转时间};/***时间片轮转调度算法结构体***/struct rr{ //定义时间片轮转调度算法结构体,里面包含得有一个进程相关的信息char name[10]; //作业名float arrivetime; //作业到达时间float servicetime; //作业服务时间float starttime; //作业开始时间float finishtime; //作业结束时间float zztime; //作业周转时间float dqzztime; //作业带权周转时间float avzztime; //作业平均周转时间float avdqzztime; //作业平均带权周转时间float lefttime; //剩余时间float stoptime; //停止时间int timeprice; //时间片设置的大小};/***静态优先级调度算法结构体***/struct sp {char name[10]; //作业号float arrivetime; //作业到达时间float servicetime; //服务时间float waittime; //等待时间float starttime; //开始运行时间float finishtime; //结束运行时间float zztime; //周转时间float dqzztime; //带权周转时间float priority; //优先权float finish; //是否已经完成}sta[10];//作业控制块,这是一个结构体数组/***最高响应比调度算法结构体***/struct task {char name[10]; //作业号float arrivetime; //作业到达时间float servicetime; //服务时间float waittime; //等待时间float finishtime; //结束运行时间float zztime; //周转时间float dqzztime; //带权周转时间float priority; //优先权float finish; //是否已经完成}JCB[10];//作业控制块,这是一个结构体数组(2)基本变量char name[10]; //作业名float arrivetime; //作业到达时间float servicetime; //作业服务时间float starttime; //作业开始时间float finishtime; //作业完成时间float zztime; //周转时间float dqzztime; //带权周转时间float avzztime; //作业平均周转时间float avdqzztime; //作业平均带权周转时间float lefttime; //剩余时间float stoptime; //停止时间int timeprice; //时间片设置的大小float priority; //优先权float finish; //是否已经完成5.具体实现5.1菜单选择模块(1)功能说明按照工作台提示,选择调度算法。

(2)函数实现过程(3)关键程序char Menu()//用来输出相关信息的函数{char choice;//用户选择while(1){system("cls");//清屏fflush(stdin);//清空缓存cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<"\t"<<" "<<"\t************进程调度算法模拟*************"<<"\t\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 1.先来先服务调度算法"<<"\t*\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 2.短作业优先调度算法"<<"\t*\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 3.时间片轮转调度算法"<<"\t\t*\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 4.静态优先级调度算法"<<"\t\t*\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 5.最高响应比优先调度算法"<<"\t*\t"<<" "<<endl;cout<<"\t"<<" "<<endl;cout<<"\t"<<" "<<"\t*\t 0.退出系统"<<"\t*\t"<<" "<<endl;cout<<"\t"<<""<<"\t*****************************************"<<"\t\t"<<" "<<endl;cout<<endl;cout<<"\t\t 请输入您的选择(0/1/2/3/4/5):"<<endl;choice=getchar();if(choice<'0'||choice>'5')//若输入有误{cout<<endl;cout<<"您的输入有误!请重新输入正确的字符! "<<endl;cout<<endl;system("PAUSE");//输出“按任意键继续”,等待用户按一个键,然后返回主菜单}elsebreak;}return choice;}5.2调度算法模块(1)先来先服务调度算法a、功能说明按照先来先服务原则调度用户输入的进程b、函数实现过程c、关键程序void DealByFCFS(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)//进程个数为1{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 sumzztime=0, sumdqzztime=0, avzztime, avdqzztime;//总的周转时间、总的带权周转时间、平均周转时间、平均带权周转时间float arrivetime=0, servicetime=0, starttime=0, finishtime=0, zztime=0, dqzztime=0;Sort(p,N);//按进程的到达时间进行排序(参数为存放进程的数组和进程个数)DealByFCFS(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N);//运行阶段,根据先来先服务的原则进行处理Print(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N); //屏幕输出处理for(int k=0; k<=N-1; k++){sumzztime=sumzztime+p[k].zztime;//总的周转时间=前一个作业的周转时间+本次作业的周转时间(循环加)sumdqzztime=sumdqzztime+ p[k].dqzztime;//总的带权周转时间=前一个作业的带权周转时间+本次作业的带权周转时间(循环加)}avzztime=sumzztime/N;//平均周转时间=总的周转时间/进程个数printf("**\n");printf("*该算法的平均周转时间为:%-.2f\t",avzztime);avdqzztime= sumdqzztime/N; //平均带权周转时间=总的带权周转时间/进程个数printf("该算法的平均带权周转时间为:%-.2f\t *",avdqzztime);printf("\n***************************************************************** **************\n ");}(2)短作业优先调度算法a、功能说明按照短作业优先原则调度用户输入的进程b、函数实现过程c、关键程序void DealBySJF(jcb *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)//进程个数为1{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 SJF(jcb *p,int N) //短作业优先调度算法处理过程{float sumzztime=0, sumdqzztime=0,avzztime,avdqzztime;//总的周转时间、总的带权周转时间、平均周转时间、平均带权周转时间float arrivetime=0,servicetime=0,starttime=0,finishtime=0,zztime=0,dqzztime=0;Sort(p,N); //按进程的到达时间进行排序(参数为存放作业的数组和作业个数)for(int m=0; m<N-1; m++){if(m==0) //进程个数为0p[m].finishtime=p[m].arrivetime+p[m].servicetime; //完成时间=到达时间+服务时间elsep[m].finishtime=p[m-1].finishtime+p[m].servicetime; //完成时间=前一个作业的完成时间+服务时间int i=0;for(int n=m+1;n<=N-1;n++){if(p[n].arrivetime<=p[m].finishtime) //找出服务时间较短的作业的个数ii++;}float min=p[m+1].servicetime;//min为服务时间最短的作业,先将服务时间较短的作业队列中的第一个付给minint next=m+1;//m+1=n ,next为服务时间最短的作业序号for(int k=m+1;k<m+i;k++) //在i个服务时间较短的作业队列中找出服务时间最短的作业{if(p[k+1].servicetime<min) //再从剩余的作业中找出运行时间最短的,从队列中第二个作业开始比较{min=p[k+1].servicetime; //第k+1个作业为新的服务时间最短的作业next=k+1;}}jcb temp;//第m+1个作业的服务时间小于第k+1个,所以交换顺序temp=p[m+1];p[m+1]=p[next];p[next]=temp;}//找到了服务时间最短的作业后DealBySJF(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N);//按短作业优先原则进行进程服务处理Print(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N);//屏幕输出处理for(int k=0; k<=N-1; k++){sumzztime=sumzztime+p[k].zztime;//总的周转时间=前一个作业的周转时间+本次作业的周转时间(循环加)sumdqzztime=sumdqzztime+ p[k].dqzztime;//总的带权周转时间=前一个作业的带权周转时间+本次作业的带权周转时间(循环加)}avzztime=sumzztime/N;//平均周转时间=总的周转时间/进程个数printf("**\n");printf("*该算法的平均周转时间为:%-.2f\t",avzztime);avdqzztime= sumdqzztime/N; //平均带权周转时间=总的带权周转时间/进程个数printf("该算法的平均带权周转时间为:%-.2f\t *",avdqzztime);printf("\n***************************************************************** **************\n ");getchar();//此处必须要有这个函数,否则就看不到显示器上面的输出,可以看到的结果只是一闪而过的一个框剪}(3)时间片轮转调度算法a、功能说明按照时间片轮转原则调度用户输入的进程b、函数实现过程c 、关键程序 void Print(rr *p,float arrivetime,float servicetime,float starttime,float finishtime,floatzztime,float dqzztime,int N) //屏幕打印输出处理{int k;printf("*调用时间片轮转调度算法以后进程的调度顺序是: ");//输出进程调度顺序printf("%s",p[0].name); //输出第一个for(k=1;k<N;k++){printf("-->%s",p[k].name); //输出第2到第N}cout<<endl; printf("*具体的进程调度信息: *\n");printf("**\n");printf("* 进程名 到达时间 服务时间 开始时间 结束时间 周转时间 带权周转时间*\n");for(k=0;k<=N-1;k++){printf("\t%s\t%-.2f\t %-.2f\t %-.2f\t %-.2f\t %-.2f\t %-.2f\n",p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime,p[k].zztime,p[k].dqzztime);}//getchar();}void ptt(rr *p,float arrivetime,float servicetime,float starttime,float finishtime,floatzztime,float dqzztime,float avzztime,float avdqzztime,float lefttime,int timeprice,int N) //时间片设置处理与程序运行{float w=0;//记录作业的停止时间int c=0;float stoptime=0; printf("请输入时间片的值:");cin>>timeprice;Sort(p,N); //按进程的到达时间排序float d[20],h[20];//分别用在服务时间和开始时间for(int k=0; k<=N-1; k++){d[k]=p[k].servicetime;//将队首进程的服务时间赋给d[k]if(k==0) //进程个数为1{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;//完成时间=前一个作业的完成时间+服务时间}h[k]=p[k].starttime;//将队首进程的开始时间赋给d[k]p[k].lefttime=p[k].servicetime-timeprice;//作业的剩余时间=服务时间-时间片的大小if(p[k].lefttime>0)//剩余时间>0(服务时间>时间片大小){c=c+1;//记录还未执行完的作业个数p[k].stoptime=p[k].starttime+timeprice;//停止时间=开始时间+时间片大小p[k].finishtime=p[k].stoptime;//完成时间=停止时间}else//剩余时间<=0(服务时间<=时间片大小)p[k].stoptime=p[k].finishtime;//停止时间=完成时间w=p[k].stoptime;//记录作业的停止时间}printf("\n***********************************结果如下************************************\n");printf("*第1轮进程调度信息: *\n");printf("**\n");printf("* 进程名到达时间服务时间开始时间停止时间剩余时间*\n");for(k=0; k<=N-1; k++){printf("*\t%s\t%-.2f\t %-.2f\t %-.2f\t %-.2f\t%-.2f\n",p[k].name,p[k].arriv etime, p[k].servicetime,p[k].starttime,p[k].stoptime,p[k].lefttime);}getchar();int i=2;//从第2轮开始,初值为2while(c>0)//还有未执行完的作业{printf("**");printf("\n*第%d 轮具体进程调度信息(时间片为%d ): *\n",i,timeprice);printf("**\n");printf("* 进程名服务时间开始时间停止时间剩余时间*\n");for(k=0;k<=N-1;k++){if(p[k].lefttime>0)//剩余时间>0(服务时间>时间片大小){p[k].servicetime=p[k].lefttime;//本次的服务时间=运行一次过后的剩余时间p[k].starttime=w;//上一个作业的停止时间就是本次作业的开始时间p[k].finishtime=p[k].starttime+p[k].servicetime;//完成时间=开始时间+服务时间p[k].lefttime=p[k].servicetime-timeprice;//剩余时间=服务时间-时间片的大小if(p[k].lefttime>0)//若作业的剩余时间仍>0(服务时间仍>时间片大小)p[k].stoptime=p[k].starttime+timeprice; //停止时间=开始时间+时间片的大小if(p[k].lefttime<=0)////剩余时间<=0(服务时间<=时间片大小){c=c-1;//完成一个作业,c减1p[k].stoptime=p[k].finishtime;//停止时间=完成时间}w=p[k].stoptime;//记录作业的停止时间printf("*\t%s\t%-.2f\t %-.2f %-.2f %-.2f\n",p[k].name,p[k].servicetime,p[k].starttime,p[k].stoptime,p[k].lefttime);printf("**\n");}}i=i+1;}if(c<=0)//所有作业调度完毕printf("\n*时间片轮转调度过程结束!*\n");printf("**");for(k=0;k<=N-1;k++) //记录信息{p[k].servicetime=d[k];//服务时间p[k].starttime=h[k];//开始时间p[k].zztime=p[k].finishtime-p[k].arrivetime;//周转时间=完成时间-到达时间p[k].dqzztime=p[k].zztime/p[k].servicetime; //带权周转时间=周转时间/服务时间}}void tt(rr *p,int N){float sumzztime=0, sumdqzztime=0, avzztime=0, avdqzztime=0;//总的周转时间、总的带权周转时间、平均周转时间、平均带权周转时间int timeprice=0;//时间片大小floatarrivetime=0,servicetime=0,starttime=0,finishtime=0,zztime=0,dqzztime=0,lefttime=0;ptt(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,avzztime,avdqzztime ,lefttime,timeprice,N);//时间片设置处理与程序运行printf("\n*综合信息为:*\n");Print(p,arrivetime,servicetime,starttime,finishtime,zztime,dqzztime,N);//屏幕打印输出处理for(int k=0;k<=N-1;k++){sumzztime=sumzztime+p[k].zztime;//总的周转时间=前一个作业的周转时间+本次作业的周转时间(循环加)sumdqzztime=sumdqzztime+ p[k].dqzztime;//总的带权周转时间=前一个作业的带权周转时间+本次作业的带权周转时间(循环加)}avzztime=sumzztime/N;//平均周转时间=总的周转时间/进程数printf("**\n");printf("*该算法的平均周转时间为:%-.2f\t",avzztime);avdqzztime= sumdqzztime/N;//平均带权周转时间=总的带权周转时间/进程数printf("该算法的平均带权周转时间为:%-.2f\t *",avdqzztime);printf("\n************************************************************* ******************\n ");getchar();}(4)静态优先级调度算法a、功能说明按照优先级调度原则调度用户输入的进程bc、关键程序int prio(int pre) //设置优先权//优先权=(等待时间+服务时间)/服务时间{int current=1,i,j;//current为当前作业for(i=0; i<N1; i++){sta[i].waittime=sta[pre].finishtime-sta[i].arrivetime; //等待时间=上一个作业的完成时间-到达时间sta[i].priority=(sta[i].waittime+sta[i].servicetime)/sta[i].servicetime;//优先权=(等待时间+服务时间)/服务时间}for(i=0; i<N1; i++){if(!sta[i].finish)//未完成{current=i; //找到第一个还没完成的作业break;}}for(j=i; j<N1; j++) //第一个还未完成的作业和后面的作业比较{if(!sta[j].finish) //还没完成(运行){if(sta[current].arrivetime<=sta[pre].finishtime) //如果作业在上一个作业完成之前到达{if(sta[j].arrivetime<=sta[pre].finishtime && sta[j].priority>sta[current].priority )current=j;// 找出到达时间在上一个作业完成之前,优先权高的作业}else //如果作业是在上一个作业完成之后到达{if(sta[j].arrivetime<sta[current].arrivetime)current=j; //找出比较早到达的一个if(sta[j].arrivetime==sta[current].arrivetime) //如果同时到达if(sta[j].priority>sta[current].priority)current=j; //找出优先权高的一个作业,即服务时间比较短的一个//优先权=(等待时间+服务时间)/服务时间}}}return current;//返回当前作业}void run(int i, int n, int pre, int staTime, int endTime){if(n==0)//进程个数为1{sta[i].starttime=sta[i].arrivetime; //开始时间=到达时间sta[i].finishtime=sta[i].starttime+sta[i].servicetime; //完成时间=到达时间+服务时间sta[i].zztime=sta[i].servicetime;//周转时间=服务时间sta[i].dqzztime=1.0;staTime=sta[i].starttime;//记录开始时间}else{if(sta[i].arrivetime>sta[pre].finishtime)//如果作业在上一个作业完成之后到达sta[i].starttime=sta[i].arrivetime; //开始时间=到达时间else//如果作业在上一个作业完成之前到达sta[i].starttime=sta[pre].finishtime; //开始时间=上一个作业的结束时间sta[i].finishtime=sta[i].starttime+sta[i].servicetime;//完成时间=开始时间+服务时间sta[i].zztime=sta[i].finishtime-sta[i].arrivetime; //周转时间=完成时间-到达时间sta[i].dqzztime=sta[i].zztime/sta[i].servicetime; //带权周转时间=周转时间/服务时间}if(n==N1-1)//到最后一个作业endTime=sta[i].finishtime;//结束时间=最后一个作业完成的时间sta[i].finish=1;//完成!!!!}void print(int i,int n){if(n==0){printf("* 名称到达时间服务时间开始时间完成时间周转时间带权周转时间*\n");}printf("*%7s%7.1f%10.1f%10.1f%10.1f%11.1f%11.1f *\n",sta[i].name,sta[i].arrivetime,sta[i].servicetime,sta[i].starttime,sta[i].finishtime,sta[i].zztime,sta[i].dqzztime);printf("**\n");}void spsa( ){int i,k;float staTime, endTime, sumzztime=0.0, sumdqzztime=0.0, avzztime, avdqzztime;int current=0, n=0, pre=0;sta[pre].finishtime=0;for(i=0; i<N1; i++){sta[i].finish=0;//所有作业未完成}printf("\n***********************************结果如下************************************\n");printf("*调用短作业优先调度算法以后进程的调度顺序是:");//输出进程调度顺序printf("%s",sta[0].name);//输出第一个for(k=1;k<N1;k++){printf("-->%s",sta[k].name);//输出第2到第N}printf("\n");printf("*具体的进程调度信息是: *\n");printf("**\n");for(n=0; n<N1; n++){current=prio(pre);//设置优先权run(current, n, pre, staTime, endTime);//执行作业print(current, n);//输出进程信息pre=current;}for(i=0; i<N1; i++){sumzztime+=sta[i].zztime;//计算总的周转时间sumdqzztime+=sta[i].dqzztime;//计算总的带权周转时间}avzztime=sumzztime/N1;//平均周转时间=总的周转时间/进程个数avdqzztime=sumdqzztime/N1;//平均带权周转时间=总的带权周转时间/进程个数printf("*该算法的平均周转时间为:%-.2f\t",avzztime);printf("该算法的平均带权周转时间为:%-.2f\t *",avdqzztime);printf("\n************************************************************* ******************\n ");}(5)最高响应比动态优先级调度算法a、功能说明按照最高响应比优先原则调度用户输入的进程b、函数实现过程c、关键程序int HRN(int pre) //设置优先权//优先权=(等待时间+服务时间)/服务时间{int current=1,i,j;//current为当前作业for(i=0; i<N; i++){JCB[i].waittime=JCB[pre].finishtime-JCB[i].arrivetime; //等待时间=上一个作业的完成时间-到达时间JCB[i].priority=(JCB[i].waittime+JCB[i].servicetime)/JCB[i].servicetime;//优先权=(等待时间+服务时间)/服务时间}for(i=0; i<N; i++){if(!JCB[i].finish)//未完成{current=i; //找到第一个还没完成的作业break;}}for(j=i; j<N; j++) //第一个还未完成的作业和后面的作业比较{if(!JCB[j].finish) //还没完成(运行){if(JCB[current].arrivetime<=JCB[pre].finishtime) //如果作业在上一个作业完成之前到达{if(JCB[j].arrivetime<=JCB[pre].finishtime && JCB[j].priority>JCB[current].priority )current=j;// 找出到达时间在上一个作业完成之前,优先权高的作业}else //如果作业是在上一个作业完成之后到达{if(JCB[j].arrivetime<JCB[current].arrivetime)current=j; //找出比较早到达的一个if(JCB[j].arrivetime==JCB[current].arrivetime) //如果同时到达if(JCB[j].priority>JCB[current].priority)current=j; //找出优先权高的一个作业,即服务时间比较短的一个//优先权=(等待时间+服务时间)/服务时间}}}return current;//返回当前作业}void runing(int i, int n, int pre, int staTime, int endTime){if(n==0)//进程个数为1{JCB[i].starttime=JCB[i].arrivetime; //开始时间=到达时间JCB[i].finishtime=JCB[i].starttime+JCB[i].servicetime; //完成时间=到达时间+服务时间JCB[i].zztime=JCB[i].servicetime;//周转时间=服务时间JCB[i].dqzztime=1.0;staTime=JCB[i].starttime;//记录开始时间}else{if(JCB[i].arrivetime>JCB[pre].finishtime)//如果作业在上一个作业完成之后到达JCB[i].starttime=JCB[i].arrivetime; //开始时间=到达时间else//如果作业在上一个作业完成之前到达JCB[i].starttime=JCB[pre].finishtime; //开始时间=上一个作业的结束时间JCB[i].finishtime=JCB[i].starttime+JCB[i].servicetime;//完成时间=开始时间+服务时间JCB[i].zztime=JCB[i].finishtime-JCB[i].arrivetime; //周转时间=完成时间-到达时间JCB[i].dqzztime=JCB[i].zztime/JCB[i].servicetime; //带权周转时间=周转时间/服务时间}if(n==N-1)//到最后一个作业endTime=JCB[i].finishtime;//结束时间=最后一个作业完成的时间JCB[i].finish=1;//完成!!!!}void check( ){int i;float staTime, endTime, sumzztime=0.0, sumdqzztime=0.0, avzztime, avdqzztime;int current=0, n=0, pre=0;JCB[pre].finishtime=0;for(i=0; i<N; i++){JCB[i].finish=0;//所有作业未完成}printf("\n***********************************结果如下************************************\n");printf("*具体的进程调度信息是: *\n");printf("**\n");for(n=0; n<N; n++){current=HRN(pre);//设置优先权runing(current, n, pre, staTime, endTime);//执行作业Print(current, n);//输出进程信息pre=current;}for(i=0; i<N; i++){sumzztime+=JCB[i].zztime;//计算总的周转时间sumdqzztime+=JCB[i].dqzztime;//计算总的带权周转时间}avzztime=sumzztime/N;//平均周转时间=总的周转时间/进程个数avdqzztime=sumdqzztime/N;//平均带权周转时间=总的带权周转时间/进程个数printf("*该算法的平均周转时间为:%-.2f\t",avzztime);printf("该算法的平均带权周转时间为:%-.2f\t *",avdqzztime);printf("\n************************************************************* ******************\n ");}6.软件运行环境及限制VC++ 6.07.结果输出及分析7.1先来先服务调度算法(1)输入值(2)运行结果7.2短作业优先调度算法(1)输入值(2)运行结果7.3时间片轮转调度算法(1)输入值(2)运行结果7.4静态优先级调度算法 (1)输入值(2)运行结果7.5最高响应比动态优先级调度算法(1)输入值(2)运行结果8.心得体会经过一周的努力,课程设计基本完成了,这次课程设计培养了我们耐心、慎密、全面地考虑问题的能力,从而加快了问题解决的速度、提高了个人的工作效率,以及锻炼围绕问题在短时间内得以解决的顽强意志。

相关主题