实验名称:作业调度模拟程序
一、实验目的
(1)掌握几种作业调度算法的原理。
(2)用代码实现作业调度算法。
二、实验原理与内容
(1) 实验内容:
编写并调试一个单道处理系统的作业等待模拟程序。调度算法:分别采用先来先服务(FCFS),最短作业优先(SJF)调度算法。对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。
(2) 实验原理:
① 先来先服务算法:按照作业提交给系统的先后顺序来挑选作业,先提交的先被挑选。
② 最短作业优先算法: 是以进入系统的作业所提出的“执行时间”为标准,总是优先选取执行时间最短的作业。
③ 作业周转时间=完成时间-提交时间
作业平均周转时间=周转时间/作业个数
作业带权周转时间=周转时间/运行时间
三、实验过程
(1)设计过程:
设计有一个作业结构体struct job,包含:
char name[10]; //作业的名字
int starttime; //作业到达系统时间
int needtime; //作业运行时间
int endtime; //作业结束时间
int runtime; //作业周转时间
double dqzztime; //带权周转时间
设计了以下函数:
void sort(struct job jobs[50],int n); //排序函数(按到达时间排序)
void FCFS(struct job jobs[50],int n); //先来先服务
void SJF(struct job jobs[50],int n); //短进程优先
void result(struct job jobs[50],int n); //输出结果函数
① 先来先服务(FCFS)设计
先来先服务调度算法: 先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
代码设计: 先将所有输入的作业通过sort()函数按到达时间的从小到大的顺序排列;再将作业分为3类:
第一类:第一个进程,i=0;
周转时间=服务时间;
结束时间=到达时间+服务时间;
第二类:第i个作业到达时,第i-1个作业运行完毕
周转时间=服务时间;
结束时间=到达时间+服务时间;
第三类:第i个作业到达时,第i-1个作业没有运行完毕
周转时间=i-1的结束时间 – i的到达时间+ i的服务时间;
结束时间=到达时间+周转时间;
带权周转时间=周转时间/服务时间。
最后调用result()函数输出结果。
② 短作业优先(SJF)设计(非抢占)
**短作业优先调度算法:**短作业(进程)优先调度算法SJ§F,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。
代码设计:
Ⅰ.先将所有输入的作业通过sort()函数按到达时间的从小到大的顺序排列;仍然将第一个进程单独拿出来:
第一个进程,i=0;
周转时间=服务时间;
结束时间=到达时间+服务时间;
Ⅱ.之后,当第0(j)个作业运行时, 统计作业到达系统的个数,记为sum;
当第0个作业运行结束后, 对已到达的sum个作业的运行时间进行排序,其中,利用strcpy()函数交换作业名字;然后令b=sum;
第二波循环: 当第b个作业运行时(即,当第0个作业运行时,最后到达的那个作业),有sum-b个作业到达系统(sum在第一次统计后没有清零,继续累加),当第b个作业运行结束后,对已到达的sum-b个作业的运行时间进行排序,
以此类推,循环反复,在外层加一个while循环,条件为sum<n (n为作业的总数量)。
**Ⅲ.作业都排好序之后,**开始运行,同先来先服务算法:
第i个作业到达时,第i-1个作业运行完毕
周转时间=服务时间;
结束时间=到达时间+服务时间;
第i个作业到达时,第i-1个作业没有运行完毕
周转时间=i-1的结束时间 – i的到达时间+ i的服务时间;
结束时间=到达时间+周转时间;
带权周转时间=周转时间/服务时间。
最后调用result()函数输出结果。
(2)问题:
本次实验在进行短作业优先调度算法代码设计中,按进程到达时间排序的设计陷入了瓶颈,最开始只设计了一个循环,导致只对第0个作业运行时到达的b个作业进行了按进程时间排序,后面的n-b-1个作业依旧按到达时间的先后运行。通过设计不同的例子与反复实验和修改,成功实现了对第0个作业之后所有作业的按进程时间排序。
(3)运行结果
运行结果如图1。
短作业优先算法的平均周转时间与平均带权周转时间都小于先来先服务算法,所以在该例子中,SJF算法优于FCFS算法。
图1 先来先服务算法和短作业优先算法的运行结果
四、实验总结
通过本次实验,我深刻的理解了操作系统中作业资源的分配方式和作业的调度方式及相关的2种算法。
操作系统实验重在理解每一个算法的意图和目的,选择适当的数据结构模拟过程就可以完成相关的算法。但是由于之前的数据结构学得不扎实,所以写代码遇到很多困难,往后要多回顾旧知识,特别是语法结构和新接触的几种作业调度的算法思想。
五、代码源码
#include<stdio.h>
#include<string.h>
struct job{
char name[10]; //作业的名字
int starttime; //作业到达系统时间
int needtime; //作业运行时间
int endtime; //作业结束时间
int runtime; //作业周转时间
double dqzztime; //带权周转时间
};
void sort(struct job jobs[50],int n);
void FCFS(struct job jobs[50],int n);
void SJF(struct job jobs[50],int n);
void result