操作系统短作业优先调度算法1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统短作业优先调度算法1
操作系统实验
题⽬:
实现⾮抢占式短作业优先调度算法
要求:
1.系统共有100个随机到达的作业。
要求为每个作业设定到达时间和需要运⾏的时间。
2.按照短作业优先进⾏调度,直到所有作业完成。
3.计算每个作业的周转时间,计算平均周转时间。
提交报告
1.实验报告打印稿(参照学校有关报告格式)。
2.刻录⼀张光盘。
光盘内容:⽤学号+姓名为每个同学建⽴⽬录,⽂件包括报告的电⼦版,
程序源代码。
⼀、主要数据结构及其说明
算法的基本概念和原理:本次课程设计主要是采⽤短作业优先算法进程的进程调度过程。
短作业优先调度算法,是指对短作业或短进程优先调度的算法。
他们可以分别⽤于作业调度和进程调度,短作业优先的调度算法是从后备队列中选择⼀个或若⼲个估计运⾏时间最短的作业,将他们调⼊内存运⾏。
⽽短进程优先调度算法则是从就绪队列中选出⼀个估计运⾏时间最短的进程,将处理机分配给他,使它⽴即执⾏并⼀直执⾏到完成,或发⽣某事件⽽被阻塞放弃处理机时再度重新调度。
本程序采⽤了⾮抢占式短作业优先调度。
⽽⾮抢占式这种⽅式,⼀旦把处理机分配给某进程后,便让该进程⼀直执⾏,直⾄该进程完成或发⽣某事件⽽被阻塞时,才再把处理机分配给其它进程,决不允许某进程抢占已经分配出去的处理机。
这种调度⽅式的优点是实现简单,系统开销⼩,适⽤于⼤多数的批处理系统环境。
但它难以满⾜紧急任务的要求——⽴即执⾏,因⽽可能造成难以预料的后果。
因此,在要求⽐较严格的实时系统中,不宜采⽤这种调度⽅式。
本课程设计主要是在满⾜要求多道单处理机的情况下进⾏短作业的优先调度。
算法的简要说明:短作业(进程)优先调度算法SJ(P)F,是指对短作业或短进程优先调度的算法。
它们可以分别⽤于作业调度和进程调度。
短作业优先(SJF)的调度算法是从后备队列中选择⼀个或若⼲个估计运⾏时间最短的作业,将它们调⼊内存运⾏。
⽽短进程(SPF)调度算法则是从就绪队列中选出⼀个估计运⾏时间最短的进程,将处理机分配给它,使它⽴即执⾏并⼀直执⾏到完成,或发⽣某事件⽽被阻塞放弃处理机再重新调度。
优点是SJ(P)F 调度算法能有效地降低作业(进程)的平均等待时间,提⾼系统吞吐量。
缺点
是该算法对长作业不利;完全未考虑作业的紧迫程度,因⽽不能保证紧迫性作业(进程)长期不被调度;由于作业(进程)的长短只是根据⽤户所提供的估计执⾏时间⽽定的,⽽⽤户⼜可能会有意或⽆意地缩短其作业的估计运⾏时间,致使该算法不⼀定能真正做到短作业游戏那调度。
该程序定义了⼀个进程数据块(struct Process_),该数据块有进程名(name)、到达时间(arrivetime)、服务时间(servicetime)、开始执⾏时间(starttime)、完成时间(finishtime)、周转时间(zztime)、带权周转时间(dqzztime)、执⾏顺序(order)。
⽤到的公式有:完成时间=到达时间+服务时间;周转时间=完成时间+到达时间;带权周转时间=周转时间/服务时间;(第⼀次执⾏的进程的完成时间=该进程的到达时间;下⼀个进程的开始执⾏时间=上⼀个进程的完成时间)。
运⾏进程的顺序需要对进程的到达时间和服务时间进⾏⽐较。
如果某⼀进程是从0时刻到达的,那么⾸先执⾏该进程;之后就⽐较进程的服务时间,谁的服务时间短就先执⾏谁(如果服务时间相同则看它们的到达时间,到达时间短的先执⾏);如果到达时间和服务时间相同,则按先来先服务算法执⾏。
⼆、程序运⾏结果
1 进⼊操作界⾯如下
2输⼊进程的信息
3 各时刻进程的状态
4 进程信息
5 平均带权周转时间界⾯
三、流程图
本次课程设计主要是通过⽐较各个进程的优先级以及各进程所需要占⽤的CPU时间来确定哪个作业优先运⾏,短作业优先调度算法除了能保证优先级更⾼的作业优先运⾏外,还能使相同优先级的前提下,所需CPU时间最短的那个作业优先运⾏,次外,本次课程设计还增加了阻塞时间和被阻塞时间来对个进程的运⾏加以控制。
此次课程设计的总体流程图如下:
四、源程序⽂件
#include
#define MaxNum 100
using namespace std;
struct Process_struct{
int Number; //进程编号
char Name[MaxNum]; //进程名称
int ArrivalTime; //到达时间
int ServiceTime; //开始运⾏时间
int FinishTime; //运⾏结束时间
int WholeTime; //运⾏时间
int run_flag; //调度标志
int order; //运⾏次序
double WeightWholeTime; //周转时间
double AverageWT_FCFS,AverageWT_SJF; //平均周转时间
double AverageWWT_FCFS,AverageWWT_SJF; //平均带权周转时间
}Process[MaxNum];
int N; //实际进程个数
int SJF(); //短作业优先
int SJF(){ //短作业优先算法
int temp_time=0; //当期那时间
int i=0,j;
int number_schedul,temp_counter; //进程编号,当前已执⾏进程个数float run_time; run_time=Process[i].WholeTime;
j=1;
while((j
{
if(Process[j].WholeTime
{
run_time=Process[i].WholeTime;
i=j;
}
j++;
}
//查找下⼀个被调度的进程
//对找到的下⼀个被调度的进程求相应的参数
number_schedul=i;
Process[number_schedul].ServiceTime=Process[number_schedul].ArrivalTime; Process[number_schedul].FinishTime=Process[number_schedul].ServiceTime+Pr ocess[number_schedul].WholeTime;
Process[number_schedul].run_flag=1;
temp_time=Process[number_schedul].FinishTime;
Process[number_schedul].order=1;
temp_counter=1;
while(temp_counter
{
for(j=0;j
{
if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].run_flag))
{
run_time=Process[j].WholeTime;
number_schedul=j;
break;
}
}
for(j=0;j
{
if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].run_flag))
if(Process[j].WholeTime
{
run_time=Process[j].WholeTime;
number_schedul=j;
}
}
//查找下⼀个被调度的进程
//对找到的下⼀个被调度的进程求相应的参数
Process[number_schedul].ServiceTime=temp_time;
Process[number_schedul].FinishTime=Process[number_schedul].ServiceTime+Pr ocess[number_schedul].WholeTime; Process[number_schedul].run_flag=1;
temp_time=Process[number_schedul].FinishTime;
temp_counter++;
Process[number_schedul].order=temp_counter;
}return 0;
}
int Pinput(); //进程参数输⼊
int Poutput(); //调度结果输出
void main()
{
int option;
printf(" ********************主菜单************************\n");
printf(" * 1 使⽤短作业优先*\n");
printf(" * 0 退出*\n");
printf("
**************************************************\n"); //system("cls");
system("color 1f");
scanf("%d",&option);
switch(option)
{
case 0:
printf("运⾏结束。
\n");
break;
case 1:
printf("对进程⽤短作业优先调度。
\n\n"); Pinput();
SJF();
Poutput();
break;
}
}
int Pinput() //进程参数输⼊
{
int i;
printf("请输⼊进程个数:\n");
scanf("%d",&N);
for(i=0;i
{
printf("***************************************\n"); printf("请输⼊⼀个进程:\n",i+1);
printf("请输⼊进程名称:\n");
scanf("%s",Process[i].Name);
printf("请输⼊到达时间:\n");
scanf("%d",&Process[i].ArrivalTime);
printf("请输⼊服务时间:\n");
scanf("%d",&Process[i].WholeTime);
Process[i].ServiceTime=0;
Process[i].FinishTime=0;
Process[i].WeightWholeTime=0;
Process[i].order=0;
Process[i].run_flag=0;
system("cls");
}return 0;
}
int Poutput() //调度结果输出
{
int i;
float turn_round_time=0,f1,w=0;
printf(" 进程名称到达T 运⾏T 开始运⾏T 结束T 执⾏顺序周转T 带权周转T\n");
for(i=0;i
{
Process[i].WeightWholeTime=Process[i].FinishTime-Process[i].ArrivalTime;
f1=Process[i].WeightWholeTime/Process[i].WholeTime;
turn_round_time+=Process[i].WeightWholeTime;
w+=f1;
printf("时刻%d :",Process[i].ServiceTime,Process[i].Name);
printf(" %s %d %d %d %d %d %f %f\n",Process[i].Name,Process[i].ArrivalTime,Process[i].WholeTime,Process[
i].ServiceTime,Process[i].FinishTime,Process[i].order,Process[i].WeightWholeTime,f
1);
}
printf("average_turn_round_timer=%f\n",turn_round_time/N);
printf("weight_average_turn_round_timer=%f\n",w/N);
return 0;
}
五、实验体会
通过本次课程设计,使我对计算机操作系统短作业优先调度算法这⼀节的知识有了更深的了解。
短作业优先调度算法易于实现,并且效率很⾼,但是短作业只考虑到短作业的利益,⽽不顾长作业,这样就可能会使得长作业⼀直处于等待状态⽽不能运⾏。
所以,短作业优先算法适⽤于系统中短作业较多的情况。
此外,通过本次实验,进⼀步巩固和复习操作系统的基础知识,更进⼀步的了解了结构化模块化程序设计的⽅法,提⾼了调试程序的技巧,提⾼了⾃⼰的动⼿能⼒我对操作系统中的作业调度模拟和短作业优先算法有了更深的认识。
并且发现,只看课本上的知识远远不够,只⼀味学习也根本没⽤,必须要动⼿亲⾃实践,才能真正掌握所学的东西。
虽然在这次课程设计过程中,我们也遇到了很多问题,但我们都能保持⼀个良好的⼼态,不急不躁,并且能通过请教⽼师,与同学们积极讨论,查看课外资料,反复实验,反复检查,将问题⼀个个解答,并最终成功的完成本次课程设计。
课程设计结束了,在这次的课程设计中不仅检验了我所学习的知识,也培养了我如何去做⼀件事情,⼜如何完成⼀件事情的能⼒。
通过模拟进程的调度问题,更加深了我对于操作系统理论的理解,在⾃⼰的动⼿操作过程中,能够体会成功的喜悦和遇到问题
⾃⼰解决的能⼒,对于我来说是⼀次提⾼,让⾃⼰多多的在实践中可以加深对理论的理解,也让我明⽩了以后应该如何更好,更⾼效的学习,在以后,我会更加努⼒。
总之,本次课程设计让我们学到了很多东西,包括课本上的和课外的,是⼀个⾮常有意义的课程设计。