范文
菜单

进程调度实验报告

时间: 04-20 栏目:报告

1进程调度实验报告

一、实验目的

作业管理是用户与操作系统的接口。作业调度的主要功能是检查系统是否能满足用户作业的资源要求以及按照一定的算法选取作业。

本实验的目的是通过模拟作业调度算法的设计加深对作业管理基本原理的理解。

二、实验内容和要求

编写并调试一个单道处理系统的作业等待模拟程序。

作业等待算法:分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。

对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。

三、实验主要仪器设备和材料

实验环境

硬件环境:IBM-PC或兼容机

软件环境:C++、C语言编程环境

四、实验原理及设计方案

1、实验原理;

由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。

作业调度算法

1.先来先服务算法:按照作业提交给系统的先后顺序来挑选作业,先提交的先被挑选。

2.最短作业优先算法:是以进入系统的作业所提出的“执行时间”为标准,总是优先选取执行时间最短的作业。

3.响应比高者优先算法:是在每次调度前都要计算所有被选作业(在后备队列中)的响应比,然后选择响应比最高的作业执行。

作业调度算法总体分析:

1.由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。

2.每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。

3.对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间。

2、设计方案

1、建立3个子函数对应3种算法,在主函数中调用它们并按格式输出相关信息;

2、按调度顺序输出作业,输出格式为:

作业编号、作业名、提交时间、运行时间、存储空间、等待时间等;

3、相关数据结构的说明

structjcb{charname[10];

charstate;

intts;

floatsuper;

inttb;

inttc;

floatti;

floatwi;

intntime;

charresource[10];

structjcb*link;

}*p*q*head=NULL;

4、程序流程图

总体流程图

A、先来先服务算法流程图

B、最短作业优先算法流程图

C、响应比高者优先算法流程图

六、调试总结及心得体会

在这个多级反馈的实验中,我采取了用一条实际上的链表队列来模拟多个逻辑上的队列,通过维护几个链表的状态信息来找到每个进程运行完后应该插入的地方,还有一个标志位Fend用来表明新插入的队列的位置。虽然实验原理很简单,但是在编写代码的过程中遇到了不少的问题,在两个小时之内已经完成的大体代码的编写,但是之中存在不少的问题,导致了用了差不多四个小时的时间去调试才把它弄好,这主要归咎于在开始设计代码的不太合理,在后期使得代码结构有些混乱,使得调试更加的麻烦,以及对编程的不熟悉。通过这个实验不仅使我对进程的调度算法有了更深的认识,使得理论知识得到的实践,也使我的编程能力得到了进一步提高。

七、思考题

1、写出每种算法的调度策略,最后比较各种算法的优缺点。

从上面的结果来分析,无疑,fcfs是最差的算法,而sfj和hrn相差不多,所以单从带权周转时间来考虑,sfj是最好的,但是它有一个缺点,长作业一直得不到执行,相比这下hrn好多了,fcfs比较有得于长作业运行,但是不得于短作业,hrn是最平衡的,即考虑了带权周转时间短,又兼顾了长短作业,但是从程序流程图可以看出,此算法最耗时间,因为每次要对ready重新排序hrn是一种折衷算法。

sfj算法易于实现,保证系统吞吐量最大。它的主要缺点是只照顾短进程。因此有可能发生下述情况,即一个进程进入系统后,由于不断有比它更短的进程进入系统而使该进程一直得不到机会运行。

2、选择调度算法的依据是什么?

这个要依据系统的目标和性能作出决定,如果要求有较少的带权周转时间可以用sfj,如果机器性能较好可以用hrn,一般来说单道系统不用fcfs。具体利弊参照以上分析。

2操作系统:进程调度实验报告

一、实验目的

1.在Linux下用C语言编程模拟优先级进程调度算法和时间片轮转进程调度算法。

2.为了清楚地观察每个进程的调度过程,每次调度程序应将各个进程的情况显示出来。

二、总体设计(设计原理、设计方案及流程等)

1、优先级进程调度算法

采用动态优先级进程调度算法,其基本思想是每次调度总是把处理机分配给优先级最高的进程,同时在运行过程中进程的优先级随着执行或等待的时间而降低或增加。

在该实验中每个进程用一个进程控制块(PCB)表示。进程控制块包含如下信息:进程号,进程名、优先数、需要运行时间、已用CPU时间、进程状态。进程号,名字,优先数,运行的时间,事先人为地指定。每个进程的状态可以是就绪,执行,阻塞或完成4种状态之一。

就绪进程获得CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。就绪队列中的进程在等待一个时间片后,优先级增1。如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时将进程的优先级减1,然后把它插入就绪队列等待CPU。

2、时间片轮转调度算法

采用简单时间片轮转调度算法,其基本思想是:所有就绪进程按FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。

三、实验步骤(包括主要步骤、代码分析等)

1.打开linux虚拟机,用vim编辑器打开代码进行修改和调整。用gcc编译器进行编译编译运行首先运行优先级算法,如图所示:

河南师范大学软件学院

2.选择轮转算法运行,如图所示:

四、结果分析与总结

本实验是利用优先级算法和轮转算法实现进程的调度,但是本代码有一个严重的缺陷,有结果图可知本实验并不能输出最后一行的信息,实验过程中计算已经运行完毕但是指针指到最后已经没有数据了。所以本实验在输出结果上少输出一次信息但是计算过程已经完毕。在修改实验的过程中遇到了很多错误都及时请教了老师和同学,最后把代码修改成功,希望老师满意。

教师签名:

年月日

3操作系统原理---进程调度实验报告

一、实验目的

通过对进程调度算法的设计,深入理解进程调度的原理。

进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。

进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。

二、实验环境

VC++6.0

三、实验内容

实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR)[提示]:

(1)先来先服务(FCFS)调度算法

原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。

将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。

按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。

(2)时间片轮转调度算法RR

操作系统原理实验报告

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程.

进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。

固定时间片轮转法:

1所有就绪进程按FCFS规则排队。

2处理机总是分配给就绪队列的队首进程。

3如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。4因等待某事件而阻塞的进程送到阻塞队列。

5系统把被唤醒的进程送到就绪队列的队尾。

可变时间片轮转法:

1进程状态的转换方法同固定时间片轮转法。

2响应时间固定,时间片的长短依据进程数量的多少由T=N×(q+t)给出的关系调整。

3根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。多就绪队列轮转法:

(3)算法类型

(4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

操作系统原理实验报告

(5)按模拟算法设计程序,运行设计的程序,观察得到的结果。

四、实验结果(含程序、数据记录及分析、实验总结等)MFC的设计框如下:

操作系统原理实验报告

实验代码以及分析:

RR算法实现分析:先根据到达时间对进程进行排序,然后调度时,超出时间片的就放至队尾,然后继续调度。

变量添加:

intm_id;IDC_EDIT_ID

用来输入进程ID

intm_reachtime;IDC_EDIT_REACHTIME用来输入进程到达时间intm_run;IDC_EDIT_RUN

用来输出正在运行的进程

intm_runtime;IDC_EDIT_RUNTIME

用来输入进程运行时间

intm_timeslice;IDC_EDIT_TIMELICE用来输入时间片

CStringm_result;IDC_EDIT_RESULT

用来输出最终调度队列

CStringm_readyqueue;IDC_EDIT_READYQUEUE

用来输出等待队列

CStringm_pcb;IDC_EDIT_PCB

用来显示输入的进程信息

数据存储:利用结构体来存储进程信息

structPCB{

操作系统原理实验报告

intid;intreachtime;intruntime;

}pcb[1000]pcb1[1000];

添加进程:

voidCMfcDlg::OnADD()

{

//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);

CStringstr1;

pcb[NO].id=m_id;

pcb[NO].reachtime=m_reachtime;

pcb[NO].runtime=m_runtime;

str1.Format("%-8d%-8d%-8d\r\n"m_idm_reachtimem_runtime);m_pcb+=str1;

m_id=0;m_id=0;

m_reachtime=0;

m_runtime=0;

NO++;

UpdateData(false);

}

RR算法

voidCMfcDlg::OnRr()

{

//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);

m_result.Empty();

UpdateData(FALSE);

UpdateWindow();

intNO2=NO;

inta[1000];

for(inti=0;i

a[i]=pcb[i].reachtime;

}

inttemp;//冒泡排序for(i=1;i

for(intj=NO-1;j>=i;j--){

if(a[j]

temp=a[j-1];

操作系统原理实验报告

a[j-1]=a[j];

a[j]=temp;

}

}

}

for(i=0;i

for(intj=0;j

if(a[i]==pcb[j].reachtime){

readyqueue[i]=pcb[j].id;

pcb1[i]=pcb[j];

}

}

}//按进程到达时间进行排序,并把排好序的进程队列赋给临时进程队列pcb1[]。

for(i=0;i

if(pcb1[i].runtime<=m_timeslice){//如果进程运行时间小于时间片m_run=pcb1[i].id;

CStringstr1;

for(intk=i+1;k

str1.Format("%d"readyqueue[k]);

m_readyqueue+=str1;

m_readyqueue+="";

}

UpdateData(FALSE);

UpdateWindow();

m_readyqueue.Empty();

Sleep(pcb1[i].runtime*1000);

}

else{//如果进程运行时间大于时间片

pcb1[NO]=pcb[i];//将该进程放至临时进程队列尾部readyqueue[NO]=pcb1[NO].id;//改变等待队列

pcb1[NO].runtime-=m_timeslice;//运行时间改变

NO++;//进程数增加

m_run=pcb1[i].id;

CStringstr1;

for(intk=i+1;k

str1.Format("%d"readyqueue[k]);

m_readyqueue+=str1;

m_readyqueue+="";

}

UpdateData(FALSE);

UpdateWindow();

操作系统原理实验报告

m_readyqueue.Empty();

Sleep(pcb1[i].runtime*1000);

}

}

m_run=0;

CStringstr;

for(i=0;i

str.Format("%d"readyqueue[i]);

m_result+=str;

m_result+="";

}

NO=NO2;//恢复以前的进程数,便于进行其他算法。UpdateData(false);

}

实验结果:

使用RR算法对进程进行调度

测试中使用的数据:时间片是2

进程到达时间运行时间

111

222

333

结果如下:

实验总结:

在该实验完成的过程中,我首先复习了进程调度的算法分析,并对这三种算法进行比较分析,同时,经过对RR算法的编写,以及MFC的设计,使我更加深入的理解了这几种算法的运算过程。在实验中也遇到许多平时并没注意到得问题,而解决这些问题又能获得很多,也感到很快乐。总之,通过这次实验,我不但进程调度的算法理解更深入,而且也同时提高了我的MFC编程模拟的能力。

4操作系统模拟实验:单处理机系统的进程调度实验报告

一、实验目的

1、加深对进程概念的理解,明确进程和程序的区别。

2、深入了解系统如何组织进程、创建进程。

3、进一步认识如何实现处理机调度。

二、实验原理

三、实验要求

1、采用时间片轮转调度算法实现进程调度。2、确定进程控制块的内容,进程控制块的组织方式。3、完成进程创建原语和进程调度原语。4、编写主函数对所做工作进行测试。

四、实验结果(程序)及分析

#include

#defineN10//系统中所允许的最大进程数量

#defineSLOT5//时间片大小

//进程状态枚举

typedefenum

{

Running//运行状态

Aready//就绪状态

Blocking//阻塞状态

}ProStatus;

//进程控制块

typedefstruct

{

intname;//进程标识符

ProStatusstatus;//进程状态

intaxbxcxdx;//通用寄存器

intpc;//程序计数器寄存器

intpsw;//程序状态字寄存器

intnext;//指向下一个进程的指针

}PCB;

//就绪队列指针

typedefstruct

{

inthead;//头指针

inttail;//尾指针

}Ready;

//模拟寄存器

intPSWAXBXCXDXPCTIME;

//PCB的静态链表

PCBpcbArea[N];//模拟PCB区域的数组

intrun;//运行状态程序的指针

Readyready;//就绪队列指针

intpfree;//空闲队列的指针

//初始化运行状态进程指针

voidInitRun()

{

run=-1;

}

//初始化就绪状态队列

voidInitReady()

{

ready.head=ready.tail=-1;

}

//初始化空闲队列

voidInitFree()

{

inttemp;

for(temp=0;temp

{

pcbArea[temp].next=temp+1;

}

pcbArea[temp].next=-1;

pfree=0;

}

//就绪队列出队

intPopReady()//返回结点在PCB区域数组的编号

{

inttemp;

if(ready.head==-1)

{

printf("就绪队列为空,不能出队。\n");

return-1;

}

temp=ready.head;

ready.head=pcbArea[temp].next;

if(ready.head==-1)

ready.tail=-1;

pcbArea[temp].next=-1;

returntemp;

}

//空闲队列出队

intPopFree()//返回结点在PCB区域数组的编号

{

inttemp;

if(pfree==-1)

{

printf("空闲队列为空,不能出队。\n");

return-1;

}

temp=pfree;

pfree=pcbArea[temp].next;

pcbArea[temp].next=-1;

returntemp;

//就绪队列入队

voidPushReady(intx)//x为入队结点的编号

{

inttemp;

if(ready.head==-1)

{

ready.head=x;

ready.tail=x;

}

else

{

temp=ready.tail;

ready.tail=x;

}

pcbArea[ready.tail].next=-1;

}

//创建PCB

voidCreatePCB(intxPCBpcb)//x为要创建PCB在PCB区域数组的编号

{

pcbArea[x].ax=pcb.ax;

pcbArea[x].bx=pcb.bx;

pcbArea[x].cx=pcb.cx;

pcbArea[x].dx=pcb.dx;

pcbArea[x].name=pcb.name;

pcbArea[x].next=-1;

pcbArea[x].pc=pcb.pc;

pcbArea[x].psw=pcb.psw;

pcbArea[x].status=pcb.status;

}

//创建进程函数

voidCreate(PCBpcb)

{

inttemp;

if(pfree==-1)

{

printf("空闲队列为空,不能创建进程。\n");

return;

}

temp=PopFree();

pcb.status=Aready;

CreatePCB(temppcb);

PushReady(temp);

//进程调度函数

voidSchedule()

{

inttemp;

if(ready.head==-1)

{

printf("系统内没有进程可以调度。");

return;

}

temp=PopReady();

pcbArea[temp].status=Running;

TIME=SLOT;//恢复CPU现场

AX=pcbArea[temp].ax;

BX=pcbArea[temp].bx;

CX=pcbArea[temp].cx;

DX=pcbArea[temp].dx;

PC=pcbArea[temp].pc;

PSW=pcbArea[temp].psw;

run=temp;//将选中的进程赋给运行指针

printf("当前运行的程序:\n");//输出调度结果

printf("进程号:%d\n"pcbArea[run].name);

printf("进程状态:%d\n"pcbArea[run].status);

printf("寄存器内容:\nAX\tBX\tCX\tDX\tPC\tPSW\n");

printf("%d\t%d\t%d\t%d\t%d\t%d\n"

pcbArea[run].axpcbArea[run].bxpcbArea[run].cxpcbArea[run].dxpcbArea[run].pcpcbArea[run].psw);

}

voidmain()

{

inttemp;

PCBtmp_pcb;

printf("请输入进程号,以负数为结束(进程号应保持唯一)。\n\n按任意键进入输入模式:");

getchar();

InitRun();

InitFree();

printf("请开始输入进程号:\n");while(1)

{

scanf("%d"&temp);

if(temp<0)

break;

tmp_pcb.name=temp;tmp_pcb.ax=temp;tmp_pcb.bx=temp;tmp_pcb.cx=temp;tmp_pcb.dx=temp;tmp_pcb.pc=temp;tmp_pcb.psw=temp;

Create(tmp_pcb);}

printf("\n");

Schedule();

为你推荐