一、实验目的
(1)掌握周转时间、等待时间、平均周转时间等概念及其计算方法。
(2)理解五种常用的进程调度算法(FCFS、SJF、HRRF、HPF、RR),区分算法之间的差异性,并用C语言模拟实现各算法。
(3)了解操作系统中高级调度、中级调度和低级调度的区别和联系。
二、实验环境
硬件环境:计算机一台,局域网环境;
软件环境:Windows或Linux操作系统,C语言编程环境。
三、实验内容和步骤
(一)实验说明
1.基本概念
程序:程序是指静态的指令集合,它不占用系统的运行资源,可以长久地保存在磁盘中。
进程:进程是指进程实体(由程序、数据和进程控制块构成)的运行过程,是系统进行资源分配和调度的一个独立单位。进程执行程序,但进程与程序之间不是一一对应的。通过多次运行,一个程序可以包含多个进程;通过调用关系,同一进程可以被多个程序包含(如一个DLL文件可以被多个程序运用)。
作业:作业由一组统一管理和操作的进程集合构成,是用户要求计算机系统完成的一项相对独立的工作。作业可以是完成了编译、链接之后的一个用户程序,也可以是各种命令构成的一个脚本。
作业调度:作业调度是在资源满足的条件下,将处于后备状态的作业调入内存,同时生成与作业相对应的进程,并为这些进程提供所需要的资源。作业调度适用于多道批处理系统中的批处理作业。根据作业控制块中的信息,检查系统是否满足作业的资源要求,只有在满足作业调度的资源需求的情况下,系统才能进行作业调度。
2. 基本调度算法
1)先来先服务(First-Come First-Served,FCFS)调度算法
先来先服务调度算法遵循按照进入后备队列的顺序进行调度的原则。该算法是一种非抢占式的算法,是到目前为止最简单的调度算法,其编码实现非常容易。该算法仅考虑了作业到达的先后顺序,而没有考虑作业的执行时间长短、作业的运行特性和作业对资源的要求。
2)短作业优先(Shortest-Job-First,SJF)调度算法
短作业优先调度算法根据作业控制块中指出的执行时间,选取执行时间最短的作业优先调度。本实验中规定,该算法是非抢占式的,即不允许立即抢占正在执行中的长进程,而是等当前作业执行完毕再进行调度。
3)响应比高者优先(HRRF)调度算法
FCFS调度算法只片面地考虑了作业的进入时间,短作业优先调度算法考虑了作业的运行时间而忽略了作业的等待时间。响应比高者优先调度算法为这两种算法的折中。响应比为作业的响应时间与作业需要执行的时间之比。作业的响应时间为作业进入系统后的等待时间与作业要求处理器处理的时间之和。
4)优先权高者优先(Highest-Priority-First,HPF)调度算法
优先权高者优先调度算法与响应比高者优先调度算法十分相似,根据作业的优先权进行作业调度,每次总是选取优先权高的作业优先调度。作业的优先权通常用一个整数表示,也叫优先数。优先数的大小与优先权的关系由系统或者用户规定。优先权高者优先调度算法综合考虑了作业执行时间和等待时间的长短、作业的缓急度,作业对外部设备的使用情况等因素,根据系统设计目标和运行环境而给定各个作业的优先权,决定作业调度的先后顺序。
本实验所选用的调度算法均默认为非抢占式调度。
实验所用的测试数据如下表所示。
本实验所用的测试数据如下表所示
作业的数据结构:
typedef struct node
{
int number; // 作业号
int reach_time;// 作业抵达时间
int need_time;// 作业的执行时间
int privilege;// 作业优先权
float excellent;// 响应比
int start_time;// 作业开始时间
int wait_time;// 等待时间
int visited;// 作业是否被访问过
bool isreached;// 作业是否已经抵达
}job;
重要函数说明
void initial_jobs()
//初始化所有作业信息
void reset_jinfo()
//重置所有作业信息
int findminjob(job jobs[],int count)
//找到执行时间最短的作业。输入参数:所有的作业信息及待查找的作业总数,输出为执行时间最短的作业id
int findrearlyjob(job jobs[],int count)
//找到达到最早的作业 输入参数:所有的作业信息及待查找的作业总数,输出参数为最早达到的作业id
void readJobdata()
//读取作业的基本信息
void FCFS()
//先来先服务算法
void SFJschdulejob(job jobs[],int count)
//短作业优先算法 输入参数:所有的作业信息及待查找的作业总数
(二)实验内容
实验代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef enum __bool {
false = 0, true = 1, } bool;
//最大作业数量
#define MAXJOB 50
//作业的数据结构
typedef struct node
{
int number;//作业号
int reach_time;//作业抵达时间
int need_time;//作业的执行时间
int privilege;//作业优先权
float excellent;//响应比
int start_time;//作业开始时间
int wait_time;//等待时间
int visited;//作业是否被访问过
bool isreached;//作业是否抵达
}job;
job jobs[MAXJOB];//作业序列
int quantity;//作业数量
//初始化作业序列
void initial_jobs()
{
int i;
for(i=0;i<MAXJOB;i++)
{
jobs[i].number=0;
jobs[i].reach_time=0;
jobs[i].privilege=0;
jobs[i].excellent=0;
jobs[i].start_time=0;
jobs[i].wait_time=0;
jobs[i].visited=0;
jobs[i].isreached=false;
}
quantity=0;
}
//重置全部作业信息
void reset_jinfo()
{
int i;
for(i=0;i<MAXJOB;i++)
{
jobs[i].start_time=0;
jobs[i].wait_time=0;
jobs[i].visited=0;
}
}
//查找当前current_time已到达未执行的最短作业,若无返回-1
int findminjob(job jobs[],int current_time)
{
int mincost = 1000;
int minloc = -1;
int i;
for(i=0;i<quantity;i++)
{
if(jobs[i].reach_time<=current_time&&jobs[i].visited == 0){
if(jobs[i].need_time<mincost){
mincost = jobs[i].need_time;
minloc = i;
}
}
}
if(minloc==-1){
int early_time=10000;
for( i = 0;i<quantity;i++){
if(jobs[i].reach_time<early_time&&jobs[i].visited!=1){
early_time = jobs[i].reach_time;