作业调度模拟程序.docx
《作业调度模拟程序.docx》由会员分享,可在线阅读,更多相关《作业调度模拟程序.docx(26页珍藏版)》请在冰豆网上搜索。
作业调度模拟程序
摘要
本次课程设计要求编写作业调度模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。
一个作业从输入初始数据到得到计算结果,要经过若干个步骤的相继执行。
例如:
编辑、编译、运行等,其中每一个步骤称作一个作业步。
把一批作业组织成输入流,通过“预输入”手段使每个作业的信息(包括作业说明书、源程序、初始数据等)暂存在辅助存储器的“输入井”中。
作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源,对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。
作业调度算法分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。
对每种调度算法都要求计算出每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。
关键词:
作业调度;作业信息;短作业优先算法;响应比高者优先算法
1绪论
1.1概述
作业的定义:
所谓作业是指在一次业务处理过程中,从输入开始到输出结束,用户要求计算机所做的有关该次业务处理全部工作。
作业的组成:
从系统角度看,作业则是一个比程序更广的概念,它由程序、数据和作业说明书组成。
作业中包含的程序和数据完成用户所要求的业务处理工作,作业说明书则体现用户的控制意图。
作业调度,又称高级调度。
其主要功能是根据一定的算法,从输人的一批作业中选出若干个作业,分配必要的资源,如内存、外设等,为它建立相应的用户作业进程和为其服务的系统进程(如输人、输出进程),最后把它们的程序和数据调人内存,等待进程调度程序对其执行调度,并在作业完成后作善后处理工作。
每个人对作业调度的算法都存在着一定的理解,这也就是很多算法实现不同的原因,可能是自己理解的不够透彻,我总觉得自己的实验不够完善,也有可能是自己掌握C语言还不够深,总觉得自己的想法与实现的算法存在着很大差距,希望通过更多的课程设计,让自己有更大的收获。
本次课程设计是用高级语言编写的作业调度的模拟程序,以加深对作业调度的算法理解。
通过该题目的设计过程,可以初步掌握作业调度的原理、软件开发方法并提高解决实际问题的能力。
编写作业调度程序,允许多个作业共行的作业调度程序。
进程调度算法采用先来先服务调度算法、最短作业优先调度算法、和最高相应比优先调度算法并计算出三中算法下平均周转时间和平均带权周转时间。
1.2需求分析
作业调度的主要功能是:
按一定的原则对外存输入井上的大量后备作业进行选择,给选出的作业分配内存、输入输出设备等必要的资源,并建立相应进程,使该作业的相关进程获得竞争处理机的权利。
另外,当作业执行完毕时,还负责回收系统资源。
在批处理系统中,作业进入系统后,先驻留在外存上,通过作业调度算法,将它们分批装入内存。
作业调度程序用于决定把外存上处于后备队列中的哪些作业调入内存,并为他们创建进程、分配必要的资源,然后,再将新创建的进程加入就绪队列中,准备执行。
应将哪些作业从外存调入内存,取决于所采用的调度算法。
最简单的是先来先服务调度算法,这是指讲最早进入外存的作业最先调入内存;较常用的一种是短作业优先调度算法,这是将外存上最短的作业最先调入内存;此外,还有基于响应比高者优先的调度算法,根据作业的等待时间和要求服务时间的和与要求服务时间之比可计算出响应比。
1.3语言选择介绍
本次课程设计是基于C语言平台设计的。
C语言主要因为它具有强大的功能,它把高级语言的基本结构和语句与低级语言的实用性结合起来。
C语言可以对位、字节和地址进行操作,而这三者是计算机最基本的工作单元。
C语言具有各种各样的数据类型,并引入了指针概念,可使程序效率更高。
另外C语言也具有强大的图形功能,支持多种显示器和驱动器。
而且计算功能、逻辑判断功能也比较强大,可以实现决策目的。
C语言系统提供了大量的标准库函数,减轻了编程的负担,所以,C语言现如今成为最受欢迎的语言之一。
2总体设计
2.1设计内容
编写并调试一个单道处理系统的作业等待模拟程序。
作业等待算法:
分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。
(1)先来先服务算法:
按照作业提交给系统的先后顺序来挑选作业,先提交的先被挑选。
(2)最短作业优先算法:
是以进入系统的作业所提出的“执行时间”为标准,总是优先选取执行时间最短的作业。
(3)响应比高者优先算法:
是在每次调度前都要计算所有被选作业(在后备队列中)的响应比,然后选择响应比最高的作业执行。
对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。
2.2设计作业调度算法
先来先服务算法比较有利于长作业,而不利于短作业。
(1)短作业(SJF)的调度算法可以照顾到实际上在所有作业中占很大比例的短作业,使它能比长作业优先执行。
SPF优先调度算法:
是从就绪队列中选出一估计运行时间最短的进程,将处理机分配给它,使它立即执行到完成,或发生某事件而被阻塞放弃处理机时,再重新调度。
为了和FCFS调度算法进行比较,我们利用FCFS算法中所使用的实例并改用SJ(P)F算法重新调度,再进行性能分析。
采用SJF算法后,不论是平均周转时间还是平均带权周转时间都有较明显的改善,尤其是对短作业D,其周转时间由FCFS算法的11降为SJF算法中的3;而平均带权周转时间是从5.5降到1.5,这说明SJF调度算法能有效地降低作业的平均等待时间和提高系统的吐量。
短作业优先调度算法对比先来先服务,不论是平均周转时间还是平均带权周转时间,都有较明显的改善,尤其是对短作业。
该算法对长作业不利,而且未考虑作业的紧迫程度,因而不能保证紧迫性作业会被及时处理。
如作业C的周转时间由10增至16,带权周转时间由2增至3.1。
更严重的是,如果有一长作业(进程)进入系统的后备队列(就绪队列),由于调度程序总是优先调度那些(即使是后进来的)短作业(进程),将致使长作业(进程)得不到调度。
(2)该算法完全未考虑作业的紧迫程度,因而不能保证紧迫性作业(进程),会得到及时处理;
(3)由于作业(进程)的长短只是根据用户所提供的估计执行时间而定,而用户又可能会有意或无意地缩短其作业的估计执行时间,致使该算法不一定能真正做到短作业优先调度。
高响应比优先调度算法在批处理系统中,用作作业调度的短作业优先算法是一个比较好的算法。
其主要缺点是作业的运行得不到保证。
如果我们能为每个作业引入前面所述的动态优先权机制,并使以速率a增加,则长作业在等待一定的时间后,必须有机会分配到处理机。
该优先权的变化可描述为:
优先权等于(等待时间+要求服务时间)除以要求服务时间。
由于等待时间加上要求服务时间,就是系统对该作业的响应时间,故该优先权又相当于响应比Rp等于等待时间加要求服务时间除以要求服务时间等于响应时间除以要求服务时间。
由上式可以看出:
(1)如果作业的等待时间相同,则要求服务的时间愈短,其优先权愈高,因而该算法有利于短作业;
(2)当要求服务的时间相同时,作业的优先权决定于其等待时间,因而实现了先来先服务;
(3)对于长作业,当其等待时间足够长时,其优先权便可升到很高,从而也可获得处理机。
该算法既照顾了短作业,又考虑了作业到达的先后顺序,也不会使作业长期得不到服务。
因此,该算法实现了一种较好的折衷。
当然,再利用该算法时,每要进行调度之前,都需先进行响应应比的计算,这会增加系统的开销。
2.3算法调用流程图
当输入作业块之后,运行界面会弹出所要选择的算法,即可输入对应的数字然后回车可进入所要运行的算法,流程图如下图2.1所示。
图2.1算法调用流程图
3详细设计
3.1功能模块划分
根据功能描述,单道批处理程序作业调度的模拟程序要求实现如下功能:
建立作业、选择作业、运行作业、计算作业周转时间和带权周转时间,以及这组作业的平均周转时间和带权平均周转时间、显示运行结果(包括每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间等)、退出程序。
各模块的功能如下:
(1)建立作业:
输入作业数,建立一组作业,并对所建立的这组作业进行
初始化,用以模拟作业调度。
初始化的内容包括作业名,作业要求运行的时间,其中,作业进入系统的时间由系统默认设置。
(2)选择作业算法:
程序通过先来先服务调度算法、短作业优先调度算法和高响应比优先调度算法对建立的一组作业进行选择,决定把哪个作业从外存调入内存中。
(3)运行作业:
根据初始化中设置的作业要求运行时间来模拟作业的运行。
(4)计算:
作业完成计算作业周转时间和带权周转时间,以及这组作业的平均周转时间和带权平均周转时间。
(5)显示结果:
将计算所得的结果输出。
(6)退出程序:
当运行结束,不再需要模拟作业调度的时候,用来退出程序。
3.2各模块代码及介绍
3.2.1作业控制块建立
该模块的作用是建立作业控制块,输入作业的信息,如作业数,作业号,作业名,作业提交时刻,作业运行时间。
最后再调用sort()函数对输入的作业按提交时间排列。
voidinput()/*建立作业控制块函数*/
{inti,num;
printf("\n请输入作业数:
?
");
scanf("%d",&num);
for(i=0;i{
printf("\n作业号No.%d:
\n",i);
j=getpch(JCB);
printf("\n输入作业名:
");
scanf("%s",j->name);
printf("\n输入作业提交时刻:
");
scanf("%f",&j->subtime);
printf("\n输入作业运行时间:
");
scanf("%f",&j->runtime);
printf("\n");
j->state='w';
j->link=NULL;
sort();/*调用sort函数*/
}
}
3.2.2短作业优先建立
该模块功能是获取队列中的最短作业使它进入就绪状态,我们先定义JCB指针,再对队列进行判断是否为空,不为空时再用IF语句进行循环判断,使最短的作业成为jcb_ready,当对首作业排队完成时,再对其他作业进行排队。
流程图如下图3.1所示。
voidSJFget()//获取队列中的最短作业
{
JCB*front,*mintime,*rear;//定义JCB指针
intipmove=0;
mintime=jcb_ready;
rear=mintime->link;
while(rear!
=NULL)if((rear!
=NULL)&&(T>=rear->subtime)&&(mintime->runtime)>(rear->runtime))
{//队列不空时,给作业排队
front=mintime;
mintime=rear;
rear=rear->link;
ipmove=1;
}
else
rear=rear->link;
if(ipmove==1){//队首作业完成,后续作业重新排队
front->link=mintime->link;
mintime->link=jcb_ready;
}
jcb_ready=mintime;
}
图3.1SJF流程图
3.2.3最高响应比优先者建立
该模块功能是获取队列中的最高响应作业,使它进入就绪状态,我们一样还是先定义JCB指针,再对队列进行判断是否为空,不为空时再用IF语句进行循环判断,使最高响应的作业成为jcb_ready,当对首作业排队完成时,改变指针指向,流程图如下图3.2所示。
voidHRNget()//获取队列中的最高响应作业
{
JCB*front,*mintime,*rear;
intipmove=0;//初始化
mintime=jcb_ready;
rear=mintime->link;
while(rear!
=NULL)
if((rear!
=NULL)&&(T>=rear->subtime)&&(mintime->Rp)<(rear->Rp))
{front=mintime;
mintime=rear;
rear=rear->link;
ipmove=1;
}
else
rear=rear->link;
if(ipmove==1){//队首作业完成,改变指针
front->link=mintime->link;
mintime->link=jcb_ready;
}
jcb_ready=mintime;
}
图3.2HRN流程图
3.3算法的优缺点及准则
(1)FCFS算法
该算法总是把处理机分配给最先进入就绪队列的进程,一个进程一旦分得处理机,便执行下去,直到该进程完成或阻塞时,才释放处理机。
优点:
实现简单,缺点:
没考虑进程的优先级。
(2)SJF算法
该算法从就绪队列中选出“下一个CPU执行期”最短的进程,为之分配处理机。
该算法虽可获得较好的调度性能,但难以准确地知道下一个CPU执行期,而只能根据每一个进行的执行历史来预测。
(3)HRN算法
该算法既照顾了短作业,又照顾了作业顺序,不会使长作业长期得不到运行,但调度前,必须计算响应比,增加了系统的开销。
(4)算法的准则
选择调度算法的依据是面向用户的准则:
周转时间短;响应时间快;截止时间的保证;优先权准则面向系统的准则:
系统吞吐量高;处理机利用率好;各类资源的平衡利用。
3.4算法中的公式
假设在单道批处理环境下有几个作业,已知它们进入系统的时间、估计运行时间。
分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法,计算出作业的平均周转时间和带权的平均周转时间。
作业i的周转时间:
Ti=Tci-Tsi
平均周转时间:
T=(T1+T2+.......+Tn)/n
作业i的带权周转时间:
Wi=Ti/Tri
带权的平均周转时间:
W=(W1+W2+.......+Wn)/n
先来先服务调度算法(FCFS):
每次调度都是从后备作业队列中,选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。
在进程调度中采用FCFS算法时,这每次调度是从就绪队列中,选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。
该进程一直运行到完成或发生某事件阻赛后,才放弃处理机。
短作业(进程)优先调度算法SJ(P)F,是指对短作业或短进程优先调度的算法。
它们可分别用于作业调度和进程调度。
该调度算法是从后备(就绪)队列中选择一个或若干个估计运行时间最短的作业(进程),将它们调度内存运行。
响应比高者优先(HRN):
每次从后备队列中选择一个或若干个估计响应比最高的作业,将它们调入内存运行。
响应比Rp=作业响应时间/运行时间
=作业等待时间+作业运行时间
=1+作业等待时间
每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:
作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。
每个作业的最初状态总是等待W。
各个等待的作业按照提交时刻的先后次序排队,总是首先调度等待队列中队首的作业。
每个作业完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后要计算并打印这组作业的平均周转时间、带权平均周转时间。
3.5主程序流程图
本程序主要是作业调度的算法问题,现实初始化程序,先建立一个作业块然后,然后选择调用算法,最后判断队列是否为空,不空继续执行,若为空则计算并打印出平均周转时间及带权平均周转时间,然后跳出程序,流程图如图3.3所示。
图3.3调度算法流程图
4调试分析
4.1建立作业块
该模块主要是先建立一个作业数控制框架,首先在程序运行后输入一个作业数,在按回车键,显示界面如下图4.1所示。
图4.1输入作业数
该模块主要是先建立一个作业的控制框架,即给定了一系列的初值,紧接着系统会自动弹出所要选择的算法,如图4.2所示。
图4.2输入作业块
4.2FCFS算法
在选择项中选FCFS项即可实现该算法,该算法实现先来先服务的功能,如下图4.3所示。
图4.3选择算法1
每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。
该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。
截图如下图4.4所示。
图4.4先来先服务算法
4.3SJF算法
在选择项中选SJF项即可实现该算法,该算法实现短作业优先的功能,如下图4.5所示。
图4.5选择算法2
短作业优先是从就绪队列中选择一个估计运行时间最短的进程,将处理器分配给该进程,使之占有处理器并执行,直到该进程完成或因发生事件而阻塞,然后退出处理器,再重新调度,如下图4.6所示。
图4.6短作业优先算法
4.4HRN算法
在选择项中选HRN项即可实现该算法,该算法实现响应比高者优先的功能,如下图4.7所示。
图4.7选择算法3
响应比高者优先是从就绪队列中选择一个响应比最高的进程,让其获得处理器执行,直到该进程完成或因等待事件而退出处理器为止。
特点:
既照顾了短进程,又考虑了进程到达的先后次序,也不会使长进程长期得不到服务,因此是一个比较全面考虑的算法,但每次进行调度时,都需要对各个进程计算响应比。
所以系统开销很大,比较复杂,如下图4.8所示。
图4.8响应比高者优先算法
5总结
现如今,计算机技术在各个方面都极大地影响了人们的生活,操作系统是现代计算机系统中必不可少的基本系统软件,操作系统作为一门计算机的基础课程,无论是对计算机等信息技术专业的学生活研究人员,还是对一般计算机应用人员,都是非常有益和重要的,也是计算机专业的必修课程和从事计算机应用人员必不可少的知识。
计算机操作系统作为计算机系统的核心,负责控制和管理整个计算机系统的软硬件资源,使之协调工作。
本次课程 设计的目的就是熟悉一些操作系统常用的算法,用C语言这个工具来实现。
我这次课程设计的课题是作业调度模拟程序,作业调度主要是完成作业从后备状态到执行状态的转变,以及从执行状态到完成状态的转变,作业调度具有强大的功能,可以记录系统中各作业的状况,包括执行阶段的有关情况;从后备队列中挑选出一部分作业投入执行;为被选中的作业做好执行前的准备工作;在作业执行结束时做善后处理工作。
由于本次课程设计实现的工具主要是C语言,所以让我对C语言的使用更加熟悉,加深了对作业调度算法的理解。
总体来说,本次课程设计应该是成功的。
虽然程序调试中遇到了各种问题,但是最终在自己的努力下还是把问题有效地解决了,让我收获很多。
通过本次课程设计我对在课堂上所学的有关操作系统的知识有了更加深刻的理解,尤其是单道批处理系统。
通过对三种调度算法的模拟程序设计,对先来先服务调度算法、短作业优先调度算法以及高响应比优先调度算法的基本概念、实现过程以及各个算法的优缺点有的了深刻的了解,知道了不同的算法类型适合不同的作业类型。
在这次课程设计中,我学到了很多知识,同时拓宽了知识面,锻炼了能力,把所学课程及相关知识加以融会贯通,也学习到了操作系统工作的方法,为今后的学习、工作打下了坚实的基础。
致谢
经过两周的努力,我完成了我的课程设计,这次课程设计培养了我耐心、细心、全面地考虑问题的能力,从而加快了问题解决的速度、提高了个人的学习效率,以及锻炼围绕问题在短时间内得以解决的顽强意志。
在本次课程设计过程中,我的能力得到了提高,同时养成了科学、严谨的作风和习惯。
在此我应该感谢给我授过课的老师,如果没有她当初的对我学习C语言的认真督促,这次的课程设计我就很难完成,同时还要感谢我的搭档以及老师给予的帮助,没他们的帮助可能有很多问题我个人不能解决。
通过本次课程设计,我要感谢我们学院为我们开设了这门操作系统课程设计,因为它为我们提供了进一步学习操作系统和巩固C语言程序计设这个平台,从而使我的知识面更为广阔,我对知识的应用能力也上升了一节,以前感觉有些模糊的知识现在都变得更加清楚,同时也肯定了自己的能力,所以这门课程设计的开设真的非常重要,特此感谢我的院校为我们开设了这门课程设计。
其实有好多东西自己认为是对的,但事实证明它是不对的,对于这一点我是深有体会,所以我在本次课程设计中特此请教了同学帮我细致的检查,并且帮我纠正了各种不符合要求的格式和布局,这样使我的课程设计说明书更加标准,更加美观。
在此,我对那些所有帮助过我的人表示深深的感谢!
参考文献
[1]汤子瀛,哲凤屏.计算机操作系统[M].西安电子科技大学学出版社,2007
[2]王清,李光明.计算机操作系统[M].冶金工业出版社,2004
[3]孙钟秀.操作系统教程[M].高等教育出版社,2003
[4]曾明.Linux操作系统应用教程[M].陕西科学技术出版社,2005
[5]张丽芬,刘利雄.操作系统实验教程[M].清华大学出版社,2006
[6]孟静.操作系统教程--原理和实例分析[M].高等教育出版社,2006
[7]周长林.计算机操作系统教程[M].高等教育出版社,2011
[8]张尧学.计算机操作系统教程[M].清华大学出版社,2010
[9]任满杰.操作系统原理实用教程[M].电子工业出版社,2006
附录:
源代码
#include"stdio.h"
#include
#definegetpch(type)(type*)malloc(sizeof(type))
structworktime{
floatTb;//作业运行时刻
floatTc;//作业完成时刻
floatTi;//周转时间
floatWi;//带权周转时间
};
structjcb{/*定义作业控制块JCB*/
charname[10];//作业名
floatsubtime;//作业提交时间
floatruntime;//作业所需的运行时间
charresource;//所需资源
floatRp;//后备作业响应比
charstate;//作业状态
structworktimewt;
structjcb*link;//链指针
}*jcb_ready=NULL:
*j;
typedefstructjcbJCB;
floatT=0;
voidsort()/*建立对作业进行提交时间排列函数*/
{
JCB*first,*second;
intinsert=0;
if((jcb_ready==NULL)||((j->subtime)<(jcb_ready->subtime)))/*作业提交时间最短的,插入队首*/
{
j->link=jcb_ready;
jcb_ready=j;
T=j->subtime;
j->Rp=1;