一、实验目的
(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;mincost = jobs[i].need_time;minloc = i;}else if(jobs[i].reach_time==early_time&&jobs[i].need_time<mincost&&jobs[i].visited!=1){mincost = jobs[i].need_time;minloc = i;}}}return minloc;
}
//查找最早到达作业,若全部到达返回-1.
int findrearlyjob(job jobs[],int count)
{int rearlyloc=-1;int rearlyjob=-1;int i; for(i=0;i<count;i++){if(rearlyloc==-1){if(jobs[i].visited==0){rearlyloc=i;rearlyjob=jobs[i].reach_time;}}else if(rearlyjob>jobs[i].reach_time&&jobs[i].visited==0){rearlyjob=jobs[i].reach_time;rearlyloc=i;}}return rearlyloc;
}
//读取作业数据
void readJobdata()
{FILE *fp;char fname[20];int i;//输入测试文件文件名printf("please input job data file name\n");scanf("%s",fname);if((fp=fopen(fname,"r"))==NULL){printf("error, open file failed, please check filename:\n");}else{//依次读取作业信息while(!feof(fp)){int num;if(fscanf(fp,"%d %d %d %d",&jobs[quantity].number,&jobs[quantity].reach_time,&jobs[quantity].need_time,&jobs[quantity].privilege)){quantity++;}}quantity--;//打印作业信息printf("output the origin job data\n");printf("---------------------------------------------------------------------\n");printf("\tjobID\treachtime\tneedtime\tprivilege\n");for(i=0;i<quantity;i++){printf("\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[i].number,jobs[i].reach_time,jobs[i].need_time,jobs[i].privilege);}}
}
//FCFS
void FCFS()
{int i;int current_time=0;int loc;int total_waitime=0;int total_roundtime=0;//获取最近到达的作业loc=findrearlyjob(jobs,quantity);//输出作业流printf("\n\nFCFS算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");current_time=jobs[loc].reach_time;//每次循环找出最先到达的作业并打印相关信息for(i=0;i<quantity;i++){if(jobs[loc].reach_time>current_time){jobs[loc].start_time=jobs[loc].reach_time;current_time=jobs[loc].reach_time;}else{jobs[loc].start_time=current_time;}jobs[loc].wait_time=current_time-jobs[loc].reach_time;printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,jobs[loc].wait_time+jobs[loc].need_time);jobs[loc].visited=1;current_time+=jobs[loc].need_time;total_waitime+=jobs[loc].wait_time;total_roundtime=total_roundtime+jobs[loc].wait_time+jobs[loc].need_time;//获取剩余作业中最近到达作业loc=findrearlyjob(jobs,quantity);}printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//短作业优先作业调度
void SFJschdulejob(job jobs[],int count) //6175432
{int i;int current_time = 0;int total_waitime=0;int total_roundtime=0;int loc;int earlyest = findrearlyjob(jobs,quantity);loc = findminjob(jobs,jobs[earlyest].reach_time);//输出作业流printf("\n\nSFJ算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");//每次循环找出最短作业作业并打印相关信息efor(i = 0;i<quantity;i++){if(jobs[loc].reach_time>current_time){jobs[loc].start_time = jobs[loc].reach_time;current_time  = jobs[loc].reach_time+jobs[loc].need_time;jobs[loc].wait_time = 0;}else{jobs[loc].start_time = current_time;jobs[loc].wait_time = current_time-jobs[loc].reach_time;current_time+=jobs[loc].need_time;}printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,jobs[loc].wait_time+jobs[loc].need_time);total_waitime+=jobs[loc].wait_time;total_roundtime+=jobs[loc].wait_time+jobs[loc].need_time;jobs[loc].visited=1;loc = findminjob(jobs,current_time);}printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
int updatePrivilege(job jobs[],int current_time){int next = -1;int max_privilege = -1;int i;while(max_privilege==-1){for(i = 0;i<quantity&&jobs[i].reach_time<=current_time;i++){if(jobs[i].visited!=1){jobs[i].wait_time = current_time-jobs[i].reach_time;jobs[i].excellent = (double)jobs[i].wait_time/(double)jobs[i].need_time;if(jobs[i].excellent>max_privilege){max_privilege = jobs[i].excellent;next = i;}}}if(max_privilege==-1){int early_time=10000,i;for(i = 0;i<quantity;i++){if(jobs[i].reach_time<early_time&&jobs[i].reach_time>current_time&&jobs[i].visited!=1){early_time = jobs[i].reach_time;next = i;jobs[i].excellent = (double)jobs[i].wait_time/(double)jobs[i].need_time;max_privilege = jobs[i].excellent;}}}}return next;
}
//高响应比调度算法
void HRRFschdulejob()
{int i,j;for(i = 0;i<quantity-1;i++){// sort reach_timefor(j =0;j<quantity-1-i;j++){if(jobs[j].reach_time>jobs[j+1].reach_time){job temp = jobs[j];jobs[j] = jobs[j+1];jobs[j+1] = temp;}}}int current_time = 0;int total_waitime=0;int total_roundtime=0;int loc = updatePrivilege(jobs,jobs[0].reach_time);printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");for(i = 0;i<quantity;i++){if(jobs[loc].reach_time>current_time){jobs[loc].start_time = jobs[loc].reach_time;jobs[loc].wait_time = 0;current_time = jobs[loc].start_time+jobs[loc].need_time;}else{jobs[loc].start_time = current_time;jobs[loc].wait_time = current_time - jobs[loc].reach_time;current_time+=jobs[loc].need_time;}printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,jobs[loc].wait_time+jobs[loc].need_time);total_waitime+=jobs[loc].wait_time;total_roundtime+=jobs[loc].wait_time+jobs[loc].need_time;jobs[loc].visited = 1;if(i!=quantity-1){loc = updatePrivilege(jobs,current_time);}}printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//优先权高者优先调度算法
void HPF(job jobs[])
{int i,j;for(i = 0;i<quantity-1;i++){// sort reach_timefor(j =0;j<quantity-1-i;j++){if(jobs[j].reach_time>=jobs[j+1].reach_time){job temp = jobs[j];jobs[j] = jobs[j+1];jobs[j+1] = temp;}}}for(i = 0;i<quantity-1;i++){// sort privilegefor(j= 0;j<quantity-1-i;j++){if(jobs[j].reach_time==jobs[j+1].reach_time&&jobs[j].privilege<=jobs[j+1].privilege){job temp = jobs[j];jobs[j] = jobs[j+1];jobs[j+1] = temp;}}}int current_time = 0;int total_waitime=0;int total_roundtime=0;int loc = 0;printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");for(i = 0;i<quantity;i++){if(jobs[loc].reach_time>current_time){jobs[loc].start_time = jobs[loc].reach_time;current_time = jobs[loc].start_time+jobs[loc].need_time;}else{jobs[loc].start_time = current_time;current_time+=jobs[loc].need_time;}jobs[loc].wait_time = jobs[loc].start_time-jobs[loc].reach_time;printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,jobs[loc].wait_time+jobs[loc].need_time);total_waitime+=jobs[loc].wait_time;total_roundtime+=jobs[loc].wait_time+jobs[loc].need_time;jobs[loc].visited = 1;int next = -1;int max_privilege = -1;for(j = 0;j<quantity&&current_time>=jobs[j].reach_time;j++){if(jobs[j].visited!=1&&jobs[j].privilege>max_privilege){max_privilege = jobs[j].privilege;next = j;}}if(next==-1){next = loc+1;}loc = next;}printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}int main()
{initial_jobs();readJobdata();FCFS();initial_jobs();readJobdata();SFJschdulejob(jobs,quantity);initial_jobs();readJobdata();HRRFschdulejob();initial_jobs();readJobdata();HPF(jobs);system("pause");return 0;
}

要求:
1、通过程序的打印信息来检查作业信息的读入是否正确。
正确

2、运行FCFS算法,检查其运算结果是否正确
正确

3、根据下图所示补充短作业优先代码,并计算其等待时间和周转时间。


4、参考以上算法的实现方法,编写高响应比优先算法和优先权高者优先算法。


四、实验总结
由四种算法的测试数据来看,算法思想不同,所需的等待时间和周转时间也不同。

由表1得出FCFS算法仅考虑作业的等待时间,等待时间长的优先考虑;SJF算法主要考虑作业的执行时间,执行时间短的优先考虑;HRRF算法同时考虑了作业的等待时间和执行时间,是FCFS和SJF算法的折中;HPF算法仅考虑作业的优先权,优先权高者先执行。
我们实验结果中可以发现对测试数据而言,并非HRRF算法的平均等待时间和平均周转时间最短。对于这组作业,SJF算法的平均等待时间和平均周转时间比 HRRF算法和HPF算法的短,说明最适合这个作业的调度算法是SJF。
由此可以得出判断算法的好坏要根据具体的作业,如果对于a作业A算法的平均等待时间和周转时间是最短的,那说明A算法是最适合a作业的调度算法。

请总结一下本次实验的收获、教训和感受,结合课本内容谈一下你对操作系统中各种作业调度算法优缺点的理解。
FCFS算法比较有利于长作业,而不利于短作业,有利于CPU繁忙型作业,而不利于I/O繁忙型作业。并且 用于批处理系统,不适于分时系统。
SJF算法易于实现,照顾了短进程,缩短了短进程的等待时间,体现了短进程优先原则,改善了平均周转时间和平均带权周转时间,有利于提高系统的吞吐量。但是对长进程不利,甚至会导致长进程长时间无法得到关注而使得系统整体性能下降,完全未考虑进程的急迫程度,因而不能保证紧迫性进程会被及时处理,进程的运行时间很难精确估计,进程在运行前不一定能真正做到短进程被优先调度。
HRRF算法既照顾了短作业又照顾了长作业,同时也照顾了先到达进程。但是调度之前需要计算各个进程的响应比,增加了系统开销,导致对实时进程无法做出及时反映。
HPF算法调度灵活,能适应多种调度需求。但是进程优先级的划分和确定每个进程优先级比较困难,同时抢占式调度增加了系统开销。

操作系统实验六:作业调度算法模拟相关推荐

  1. 操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)

    实验二 进程调度 一.     实验目的 1.       理解进程运行的并发性. 2.       理解处理器的三级调度. 3.       掌握先来先服务的进程调度算法. 4.       掌握短 ...

  2. 操作系统实验之作业调度算法

    #include <iostream.h>#include <stdio.h> #include <string.h> #include<stdlib.h&g ...

  3. 操作系统实验六--设备管理

    文章目录 操作系统实验六--设备管理 一.实验目的 二.实验内容 三.设计原理及相关算法 四.结果分析 五.源代码 操作系统实验六–设备管理 一.实验目的 1.通过实验,进一步了解设备独立性的概念: ...

  4. 计算机操作系统实验:银行家算法模拟

    目录 前言 实验目的 实验内容 实验原理 实验过程 代码如下 代码详解 算法过程 运行结果 总结 前言 本文是计算机操作系统实验的一部分,主要介绍了银行家算法的原理和实现.银行家算法是一种用于解决多个 ...

  5. 操作系统实验七 磁盘调度算法的模拟与实现(C语言)

    实验七 磁盘调度算法的模拟与实现 1 .实验目的 (1) 了解磁盘结构以及磁盘上数据的组织方式. (2) 掌握磁盘访问时间的计算方式. (3) 掌握常用磁盘调度算法及其相关特性. 2 .实验基本知识及 ...

  6. 操作系统实验六 设备管理

    实验六 设备管理 一.实验目的 1. 理解设备管理的概念和任务. 2. 掌握独占设备的分配.回收等主要算法的原理并编程实现. 二.实验内容与基本要求 1. 在Windows系统中,编写程序实现对独占设 ...

  7. 操作系统实验六、系统内存使用统计

    实验六:系统内存使用统计 一.实验目的 1.了解windows内存管理机制,理解页式存储管理技术. 2.熟悉Windows内存管理基本数据结构. 3.掌握WIndows内存管理基本API的使用. 二. ...

  8. 操作系统实验六:Linux下的C语言编程

    实验六 Linux下的C语言编程 一.实验要求 (1)熟悉Linux环境下C语言应用程序开发的基本过程: (2)熟悉基本库函数的使用: (3)具有初步的应用程序设计能力. 二.实验内容 (1)有三个程 ...

  9. 作业必备:操作系统实验六【生产者消费者实验:用信号量实现PV操作】

最新文章

  1. 1005. 继续(3n+1)猜想 (25) (ZJUPAT 数学)
  2. alpinestars与丹尼斯_骑行靴|丹尼斯VS A星心得分享,它和普通鞋子不同之处竟在这里!...
  3. Spring框架基于AspectJ的AOP开发规范和步骤
  4. C++模板声明与实现分开--由此想到的编译,链接原理
  5. PEP 20 -- The Zen of Python(Python之禅)
  6. ‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
  7. SpringBoot 中@Autowired 注入失效原因及解决方法
  8. Linux下安装MySQL数据库、禅道
  9. linux 安卓svn,linux安装svn
  10. 机器学习基础(五十六)—— tanh、sign 与 softsign
  11. [django]自定义标签和过滤器
  12. linux运维常用命令大全150条
  13. 攻城狮算保险--理财型,还是消费型?
  14. Java电商秒杀系统性能优化(八)——流量削峰技术-削峰填谷之神级操作
  15. 【WIFI专题】Wifi 2.4G及5G频段各信道的中心频率及主要国家的分布情况
  16. Matplotlib风格与样式
  17. 深入理解AQS之ReentrantReadWriteLock详解
  18. 爱我所爱,行我所行,听从我心,无问西东
  19. 基础知识redis详解--【Foam番茄】
  20. 【Linux从青铜到王者】第二十三篇:Linux网络基础第四篇之kcp协议

热门文章

  1. 微信小程序开发注意事项
  2. vi 编辑器进入后无法退出
  3. FDC2214学习笔记
  4. Cglib之Enhancer创建动态代理
  5. 理解断路器CircuitBreaker的原理与实现
  6. 小陈java学习笔记0803
  7. 中国消费级无人机行业发展态势及前景战略规划建议报告2021-2027年
  8. 如何使用github(萌新向)
  9. matplotlib 怎么画核密度
  10. 计算机电源管理最高续航,高效电源管理 vivo TWS Neo最大支持27小时续航