进程调度模拟程序课程设计

更新时间:2024-04-22 03:46:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《操作系统》课程设计报告

专业: 计算机科学与技术 班级: 09计本班

学 号 200981010118 姓 名 刘利刚 成绩

题目名称: 进程调度模拟程序

完成日期: 2012年6月20日

甘肃政法学院计算机科学学院

目 录

第一章 课程设计目的................................................. 3 第二章 课程设计要求................................................. 3 第三章 设计思想..................................................... 4

3.1 基本概念 .................................................... 4 3.2 进程控制块 .................................................. 5 3.3 算法思想 .................................................... 5 第四章 详细设计..................................................... 6

4.1 程序设计流程图 .............................................. 6 4.2 程序各模块功能介绍 .......................................... 7 第五章 运行结果及分析.............................................. 14

5.1 程序调试 ................................................... 14 5.2 运行结果 ................................................... 15 5.3 结果分析 ................................................... 17 第六章 总结........................................................ 17 参考文献........................................................... 18

进程调度模拟程序

第一章 课程设计目的

深入掌握进程调度的概念原理和实现方法,理解操作系统进程管理中进行进程调度的过程和编程方法,掌握先来先服务调度算法和最高优先数优先的调度算法,创建进程控制块PCB。理解进程的状态及变化,动态显示每个进程的当前状态及进程的调度情况。进程调度是处理机管理的核心内容。本次课程设计用C语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会最高优先数优先与按时间片轮转调度结合算法的优缺点。

第二章 课程设计要求

编写一个进程调度程序,允许多个进程并行执行。

1、进程调度算法:采用最高优先数优先与按时间片轮转调度结合算法。 2、每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。 3、进程的优先数及需要的运行时间可在运行时输入,进程的到达时间为输入进程的时间。

4、进程的运行时间以时间片为单位进行计算。

5、每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

6、就绪进程获得 CPU后都只能运行一个时间片。

7、如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低

一级),然后把它插入就绪队列等待CPU。

8、每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。

重复以上过程,直到所要进程都完成为止。

第三章 设计思想

3.1 基本概念

优先级调度算法:按照进程的优先级大小来调度。使高优先级进程或线程得到优先的处理的调度策略称为优先级调度算法。进程的优先级可以由系统自动地按一定原则赋给它,也可由系统外部来进行安排。本次课程设计是自己给定进程的优先级。

但在许多采用优先级调度的系统中,通常采用动态优先数策略。即一个进程的优先级不是固定的,往往是随许多因素的变化而变化。尤其随作业(进程)的等待时间,已使用的处理器时间或其他系统资源的使用情况而定,以防止低优先级进程或线程长期饥饿现象发生

时间片轮转算法: 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。时间片轮转算法主要用于处理器调度。采用此算法的系统,其进程就绪队列往往按进程到达的时间来排序。进程调度程序总是选择就绪队列中的第一个进程,也就是说按照先进先出原则调度,但一旦进程占有处理器仅使用一个时间片,在使用完一个时间片后,进程还没有完成其运行,它也必须释放出(被抢占)处理器给下一个就绪的进程。而被抢占的进程返回到就绪队列的末尾重新排队等候再次运行。

进程调度程序选择一个就绪状态的进程,使之在处理器上运行,每个进程的

状态信息用数据结构(进程控制块PCB)表示,进程的调度采用最高优先数优先和按时间片轮转相结合的调度算法,并且采用动态优先数策略,选择进程占用处理器后该进程仅能使用一个时间片,运行完后优先数减1。 进程的状态:

运行状态R(Run):进程正在处理器上运行。

就绪状态W(Wait):一个进程获得了除处理器外的一切所需资源,一旦得到处理器即可运行。

完成状态F(Finish):一个进程一旦完成,就停止运行。 3.2 进程控制块

描述进程的状态信息,用结构体定义 typedef struct process

{ char name[10]; //进程名

int priority; //优先数 Time ReachTime; //到达时间 Time NeedTime; //需要运行时间 Time UsedTime; //已用时间 char state; //进程状态

}PCB; //进程控制块 进程调入 AddProcess()函数 打印进程print() 函数 进程调度attemper()函数 图1 进程调度模拟程序模块图

3.3 算法思想

定义结构体PCB描述进程的进程控制块,定义数组PCB pcb[Max]存放进程 进程调度程序调用face()函数选择所要进行的操作。输入1则增加进程并调度

选择操作 face() 函数 进程优先级排序sort()函数 进程调度模拟程序

进程;输入2则打印进程,输入0则任务结束;增加进程,调用AddProcess()函数,将输入的进程存放在数组pcb[Max]中;打印进程,调用print()函数,在该函数中首先调用sort()函数对进程按优先级和先来先服务排序,然后显示输出排序后的进程。进程调度,调用attemper()函数,调度优先级最高的进程分配给CPU使之运行一个时间片,进程优先级排序,调用sort()函数,按照先来先服务和优先级排序,使排序完最优先运行的进程存放在pcb[0]中。

第四章 详细设计

4.1 程序设计流程图 开始 选择 设置时间片 是 增加进程 结束进程 打印进程 继续增加 结束 否 优先级排序 打印进程 进程调度 完成 真

图2 程序设计流程图

4.2 程序各模块功能介绍

<1> 进程优先级排序sort( )函数:函数用冒泡法排序,首先按到达时间排序,使到达时间最早(即pcb[n].ReachTime最小)的进程被交换到pcb[0]中,再按优先级排序,使具有最高优先级(即pcb[n].priority最大)的进程被交换到pcb[0]中。相同优先级的进程只按到达时间排序 。 主要代码如下:

for (i=0;i=i;j--)

{ if (pcb[j+1].ReachTime

for (i=0;i=i;j--)

{ if (pcb[j+1].priority>pcb[j].priority)

{ temp=pcb[j]; }

pcb[j]=pcb[j+1]; pcb[j+1]=temp;

{

temp=pcb[j];

pcb[j]=pcb[j+1]; }

pcb[j+1]=temp; }

} }

进程优先级排序Sort()函数的流程图如图3所示。

开始 i=0 j=n-2 i=0 temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; j=j-1 pcb[j+1].ReachTimepcb[j].priority temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; Y j=j-1 j>=i N Y j>=i N i=i+1 i=i+1 i

图3 sort( )函数流程图

结束 <2> 打印进程print( )函数:先调用sort()排序函数对进程进行排序,排序完再打印输出进程 主要代码如下: sort();

printf(\进程名 优先级 到达时间 需要时间 已用时间 进程状态 \\n\

for (i=0;i

{printf(\

ReachTime,pcb[i].NeedTime,pcb[i].UsedTime,pcb[i].state);

}

<3> 进程调入AddProcess()函数:增加进程函数,输入要添加的进程的进程控制块的信息,并依次存放在数组PCB pcb[Max]中,每加入一个进程后判断是否还要继续增加进程,若是则继续循环的执行操作 主要代码如下: do {

printf(\请输入进程名\

scanf(\

printf(\请输入进程的优先级\

scanf(\

printf(\请输入进程需要的时间\

scanf(\

pcb[n].ReachTime=n; pcb[n].UsedTime=0; pcb[n].state='W';

n++;

printf(\还要继续增加进程吗,是(Y),否(N)\ do {

ch=getchar();

} while(ch!='Y'&&ch!='N'&&ch!='y'&&ch!='n');

}while (ch=='Y'||ch=='y');

打印进程print( )函数和进程调入函数AddProcess()函数的流程图如图4和图5所示。

开始 开始 输入pcb[n] 进程信息

i=i+1 ch=getchar() sort()排序 i=0 n=n+1 输出pcb[i]进程信息 继续增加进程 i

图 5 AddProcess()函数流程图 <4> 进程调入attemper( )函数:调度排完序后存放在pcb[0]中的进程,分配给该进程CPU,使之运行一个时间片,然后比较进程的剩余时间(pcb[0].NeedTime-pcb[0].UsedTime)是否小于时间片的大小pTime,若是,则该进程调度完成,进程处于完成状态,若非,则已用时间加上一个时间片,进程处于就绪状态继续等待运行,然后调用print( )函数打印输出当前进程的状态并排序,直至所有进程处于完成状态后结束运行。

主要代码如下: do {

if ((pcb[0].NeedTime-pcb[0].UsedTime)>pTime)

{ pcb[0].UsedTime+=pTime; //已用时间加时间片 else

{ pcb[0].UsedTime=pcb[0].NeedTime; //已用时间等于需要时间

pcb[0].priority=-1000;//优先级置为零 pcb[0].state='F';//完成进程,将状态置为完成 }

pcb[0].priority--;//优先级减一 pcb[0].state='W'; }

print();

}while(pcb[0].state!='F');

进程调入attemper( )函数流程图如图6所示。

开始 (pcb[0].NeedTime-pcb[0].UsedTime)>pTime N Y

pcb[0].UsedTime+=pTime pcb[0].priority— pcb[0].state='W' pcb[0].UsedTime=pcb[0].NeedTime pcb[0].priority=-1000 pcb[0].state='F'

pcb[0].state!='F' N print() 打印 Y 结束

图6 attemper( )函数流程图

<5> 选择操作face( )函数:函数打印所能进行的操作以供选择。输入1则是增加进程后调度进程,输入2则是打印进程,输入0则是任务结束。 主要代码如下: char choose;

printf(\增加进程并调度进程,请按1\ printf(\打印进程,请按2\ printf(\任务结束, 请按0\ printf(\请选择:\do{

choose=getchar();

} while(choose!='1'&&choose!='2'&&choose!='0'); return choose; }

选择操作face( )函数流程图如图7所示。

开始 增加进程并调度进程,请按1 打印进程,请按2 任务结束, 请按0 请选择: choose=getchar() e!='2'&&choose!='0' N Y return choose 结束 choose!='1'&&choos

图7 face( )函数流程图

<6> main( )函数:首先设置时间片的大小pTime,然后调用face()函数选择要进行的操作,choose='1'则增加进程并调度,choose='2'则打印进程,choose='0'则任务结束。 主要代码如下: char choose;

n=0; //初始化进程数为0 printf(\设置时间片的大小:\ scanf(\ choose=face(); do

{ if (choose=='1') { AddProcess();

print(); attemper();

}

if (choose=='2') { print(); }

if (choose=='0') { return; }

choose=face(); } while(1); 函数间的关系:

1)sort( )函数嵌套在print()函数中调用

2)调用AddProcess()函数前必须先调用print()函数对进程进行排序并打印。

Main()函数的流程图如图8所示。

开始 n=0;

设置时间片的大小pTime choose=face() choose= ='1' Y choose= ='2' N

AddProcess(); print(); attemper(); Y print(); N return 真 图8 main( )函数流程图

第五章 运行结果及分析

5.1 程序调试

此次课程设计进程调度模拟程序是用C编写的程序,运行环境是Microsoft Visual C++6.0。在VC++6.0中的编写的程序如图9所示。

图 9 vc++6.0中调试程序

5.2 运行结果

首先设置时间片大小,然后根据提示,选择1创建进程,输入进程的名称,该进程的优先级,该进程需要的运行时间。然后依次创建三个进程,详细信息如图10所示。

图 10 创建三个进程的详细信息

点击回车键,运行创建的三个进程,运行过程如图11所示。

图 11 三个进程的运行过程

上述创建的三个进程运行完以后,还可以继续创建新的进程继续运行。如图12所示。

图 12 新创建进程的运行过程

5.3 结果分析

运行程序后,首先根据提示设置时间片大小为10,然后顺序创建三个进程llg,lly,llt,它们的优先级依次为5,8,4,需要运行的时间为20,10,16,程序默认三个进程到达的时间依次为0,1,2。运行进程,首先比较优先级大小,选择进程lly运行,其进程状态为R(运行),其运行一个时间片时间以后,该进程运行完成,优先级减变为-100(程序默认),然后其进程状态变为F(完成);再选择llg进程运行,首先其进程状态从W(等待)变为R(运行),然后运行一个时间片时间以后,该进程还没运行完成,其优先级减1变为4,相比llt进程,他们具有相同的优先级,所以继续运行llg进程,再运行一个时间片以后,该进程运行完成,其优先级变为-100(程序默认),其进程状态从R(运行)变为F(完成);最后运行llt进程,首先它的进程状态运行一个时间片以后,换没结束,再运行6以后运行结束,其优先级变为-100(程序默认),其进程状态从R(运行)变为F(完成)。至此,创建的三个进程运行完毕,换可以创建新的进程运行,如图12所示。

第六章 总结

通过此次课程设计,我掌握进程调度的相关知识,特别是结和最高优先级优先算法和按时间轮转算法有了新的认识。课程设计和平时的实验课比较起来有很大的差距,实验课只是将这一章中的一部分内容练习操作一遍,而课程设计需要的是他们综合起来的东西,这要更难一些。此次课程设计主要遇到的困难就是,最高级优先数优先算法和按时间片轮转法的算法的结合,经过查阅资料和自己多次的调试,终于使编写的程序达到了预期的效果。

总体来说我认为操作系统这门学科在计算机科学当是中非常重要的。这次操作系统的课程设计收获颇丰,复习了许多东西,也从新学会了许多东西。我想这也许就是课程设计的最终目的吧。

参考文献

[1]刘振安、刘燕君著.《C++程序设计课程设计》.北京: 机械工业出版社,2004

[2][美]Abraham Silberschatz, Peter Baer Galvin, Greg Gagne 著. 郑扣根 译. 操作系统概念(第六版). 北京: 高等教育出版社,2004

[3]陈向群,向勇 等. Windows操作系统原理(第二版). 北京:机械工业出版社,2004. [4]Mark E.Russinovich, David A. Solomon. Microsoft Windows Internals 2005 [5]Jhnson M.Hart. Windows System,3rd Edition. Addsion wesley Profession.2004

本文来源:https://www.bwwdw.com/article/m3op.html

Top