黄若耘
姓名
学号 2015210880
实验
成绩
华中师范大学计算机科学系
实 验 报 告 书
实验题目: 作业调度算法
课程名称:
操作系统
主讲教师: 叶俊民 教授
辅导教师:
课程编号:
班 级:
实验时间:
2017.9.28
一、实验目的:
1、 已知 n 个作业的进入时间和估计运行时间(以分钟计)单道环境下,分别用先来
先服务调度算法、短作业优先调度算法、响应比高者优先调度算法,求出批作业
的平均周转时间和带权平均周转时间;在多道环境(如 2 道)下,求出这些作业
的平均周转时间和带权平均周转时间
2、 就同一批次作业,分别讨论这些算法的优劣;
3、 衡量同一调度算法对不同作业流的性能。
二、实验内容:
1、先来先服务算法
2、最短作业优先算法
3、最高响应比优先算法
三、实验环境:
1、PC 机。
2、Windows 环境。
3、CodeBlocks
四、实验设计原理
1、先来先服务算法:按照作业提交给系统的先后顺序来挑选作业,先提交的先被挑选。
2、最短作业优先算法:是以进入系统的作业所提出的“执行时间”为标准,总是优先
选取执行时间最短的作业。
3、响应比高者优先算法:是在每次调度前都要计算所有被选作业(在后备队列中)的
响应比,然后选择响应比最高的作业执行。
4、两道批处理系统中最短作业优先调度算法:内存中可以进入两个作业,这两个作业
按照最短作业优先调度算法调整作业执行的次序。
五、实验详细实现过程与算法流程
1、 先来先服务
第一个进入输入井的作业先执行,那么该作业就有一个执行结束的时间,那么在该
作业运行时间内,满足时间条件的作业进入输入井,然后根据前一个作业的运行结束
的时间推算和下一个作业要进入输入井的时间推算下一个作业时间开始运行的时间:
Time = max(curendtime,nextstarttime);这样后作业运行的开始时间就计算出来
了,
那么加上一个运行长度就是该作业的结束时间,周转时间即为结束时间减去进入输入
井的时间
2、最短作业优先算法
这里设置一个优先队列,第一个作业先进入队列,第一个作业出队列,根据出队的
作业的结束时间扫描能够满足条件的作业进入队列,重复如此操作直到作业调度完毕,
在这个过程中,出队的作业,就能根据前一个作业的信息推算出当前作业的信息
3、最高响应比优先算法
这里采用了蛮力法:根据当前运行的作业的信息,再枚举输入井中等待运行的作业,
算出等待运行作业的响应比,选择最大的执行,这样直到作业运行完毕
六、实验调试与结果分析(问题的发现、分析、解决方案与创新)
1、在单道环境下,已知 n 个作业的进入时间和估计运行时间(以分钟计),得到的每
一个作业的开始时间、结束时间、周转时间、带权周转时间,以及这些作业的平均周
转时间和带权平均周转时间;
2、同一调度算法对不同作业流的性能,每个算法有三个测试作业流
先来先服务作业调度
最短优先服务作业调度
最高响应比优先服务作业调度
在 2 道环境下,已知 n 个作业的进入时间和估计运行时间(以分钟计),得到的每一个
作业的开始时间、结束时间、周转时间、带权周转时间,以及这些作业的平均周转时
间和带权平均周转时间。
7、源程序(加注释)
1、先来先服务算法
class Job
{
String name;//作业
int hour;//进入时间(小时)
int min;//进入时间(分钟)
int start_hour;//开始时间
int start_min;
int run;//运行时间
int over_hour;//结束时间
int over_min;
int cycling;//周转时间
double wi;//带权周转时间
Job(String name,int hour,int min,int run)
{
this.name=name;
this.hour=hour;
this.min=min;
this.run=run;
}
}
public class FCFS
{
public static void main(String args[])
{
double sum_c=0,sum_w=0;
double ave_c,ave_w;
Job job[]=new Job[4];
job[0]=new Job("JOB1",8,00,120);
job[1]=new Job("JOB2",8,50,50);
job[2]=new Job("JOB3",9,00,10);
job[3]=new Job("JOB4",9,50,20);
job[0].start_hour=job[0].hour;
job[0].start_min=job[0].min;
job[0].over_hour=(job[0].start_hour*60+job[0].run)/60;
job[0].over_min=(job[0].start_hour*60+job[0].run)%60;
for(int i=1;i<4;i++)//计算开始时间和结束时间
{
job[i].start_hour=job[i-1].over_hour;
job[i].start_min=job[i-1].over_min;
job[i].over_hour=(job[i].start_hour*60+job[i].start_min+job[i].run)/60;
job[i].over_min=(job[i].start_hour*60+job[i].start_min+job[i].run)%60;
}
for(int j=0;j<4;j++)//计算周转时间和带权周转时间
{
job[j].cycling=(job[j].over_hour*60+job[j].over_min)-
(job[j].hour*60+job[j].min);
job[j].wi=job[j].cycling/(job[j].run*1.0);
}
for(int n=0;n<4;n++)
{
sum_c+=job[n].cycling;
sum_w+=job[n].wi;
}
ave_c=sum_c/4;
ave_w=sum_w/4;
for(int m=0;m<4;m++)
{
System.out.println(job[m].hour+":"+String.format("%02d",job[m].min)+"
"+job[m].run+"
"+job[m].start_hour+":"+String.format("%02d",job[m].start_min)+" "
+job[m].over_hour+":"+String.format("%02d",job[m].over_min)+"
"+job[m].cycling+" "+job[m].wi);
}
System.out.println("作业平均周转时间 T="+ave_c+"分钟"+"
总周转
时间:"+sum_c+"分钟");
System.out.println("作业带权平均周转时间 W="+ave_w+" 总带权周转时间:
"+sum_w);
}
}
2、最短作业优先算法
voidsfc(Jcb J[],int n)//最短作业优先作业调度算法
{
queue qjob;
qjob.push(&J[0]);
inttime=J[0].enter.hour*60+J[0].enter.minute+J[0].operation;//上一个作业的
结束时间
J[0].state=1;
int t=n-1;
while(t)
{
int i=1;
while(J[i].state)
{
i++;
}
for(int j=i;jtime)
break;//如果这个作业还没来到,则停止继续比较,只考虑已经
进入就绪队列的作业
if(J[j].state==0 &&(J[i].operation>J[j].operation))
{
i=j;
}
}
qjob.push(&J[i]);
J[i].state=1;
time+=J[i].operation;
t--;
}
runing(qjob,n);
display(J,n);
}
3、最高响应比算法
#include
#include
using namespace std;
struct JOB//作业结构体
{
string name; //进程名
float arrivetime;//到达时间
float servicestime;//服务时间
float starttime; //开始时间
float finishtime;//完成时间
float zztime; //周转时间
float dqzztime; //带权周转时间
int sfzx;//是否执行标志位 1 已执行 0 未执行
float xyb;//记录响应比
};
//获取下一个要执行的工作的服务时间
string search_min(JOB job[],int nowtime)
{
//记录符合条件的作业的中间
JOB job_hrrn[6];
//给中间数组赋值
for(int n=0;n<6;n++)
{
//符合条件的话赋值
if(job[n].arrivetime<=nowtime && job[n].sfzx==0)
{
job_hrrn[n].servicestime=job[n].servicestime;
job_hrrn[n].name=job[n].name;
job_hrrn[n].arrivetime=job[n].arrivetime;
float waittime=nowtime-job_hrrn[n].arrivetime;
float d=waittime+job_hrrn[n].servicestime;
job_hrrn[n].xyb=d/job_hrrn[n].servicestime;
//cout<job_hrrn[j].xyb)
{
temp_xyb=job_hrrn[i].xyb;
temp_name=job_hrrn[i].name;
job_hrrn[i].xyb=job_hrrn[j].xyb;
job_hrrn[i].name=job_hrrn[j].name;
job_hrrn[j].xyb=temp_xyb;
job_hrrn[j].name=temp_name;
}
}
}
}
/*for(int w=0;w<6;w++)
{
cout.width(9);
cout<=0;k--)
{
//去掉不符合条件的作业
if(job_hrrn[k].xyb!=-1)
{
//num=job_servicetime[k].servicestime;
name=job_hrrn[k].name;
break;
}
}
//返回 num
return name;
}
int input()//输入作业信息函数
{
//输入操作
//只记录三个字段的结构体
JOB job_th[6];
//循环输入操作
for(int q=0;q<6;q++)
{
cout<<"\n 请输入作业名,到达时间,运行时间:";
cin>>job_th[q].name>>job_th[q].arrivetime>>job_th[q].servicestime;
//标志是否已经执行
job_th[q].sfzx=0;
}
JOB job_si[6];//记录七个字段的结构体
//sfzx 字段初值为 0(表示未执行)
for(int s=0;s<6;s++)
{
job_si[s].sfzx=0;
}
//给第一个作业赋值
job_si[0].name=job_th[0].name;
job_si[0].arrivetime=job_th[0].arrivetime;
job_si[0].servicestime=job_th[0].servicestime;
job_si[0].starttime=job_si[0].arrivetime;
job_si[0].finishtime=job_si[0].arrivetime+job_si[0].servicestime;
job_si[0].zztime=job_si[0].finishtime-job_si[0].arrivetime;
job_si[0].dqzztime=job_si[0].zztime/job_si[0].servicestime;
job_si[0].sfzx=1;//更新执行状态
job_th[0].sfzx=1;//更新执行状态
//记录 job_si 结构体的成员数量
int index=0;
//算法核心部分
for(int g=1;g<6;g++)
{
//获取下一个工作名称
string name=search_min(job_th,job_si[index].finishtime);
//string name=search_min(job_th,job_si[0].finishtime);
//cout<