时间片轮转、强占式短进程优先算法
《抢占式调度》课件

3
嵌入式系统
应用于嵌入式设备,如智能手机和家用电器。
抢占式调度的算法及其实现
1 优先级算法
根据进程的优先级决定 执行顺序。
2 轮转算法
按照时间片轮转方式切 换进程执行。
3 最短进程优先算法
优先执行执行时间最短 的进程。
抢占式调度和非抢占式调度的比较
抢占式调度 非抢占式调度
允许中断正在执行的进程 等待当前进程执行完成后再切换
实时系统中的抢占式调度
硬实时系统
任务具有严格的时间限制和 硬性约束。
软实时系统
任务具有软性约束,可容忍 一定范围的违约。
周期性任务
按照固定的时间周期执行。
抢占式调度在操作系统中的应用
1
实时操作系统
用于处理实时任务,如航空交通管制系统。
2
多任务操作系统
支持同时执行多个任务,如Windows和Linux。
《抢占式调度》PPT课件
抢占式调度是一种操作系统调度方式,本课件将介绍抢占式调度的概念、种 类、优点、以及它在实时系统和多线程编程中的应用等。
ቤተ መጻሕፍቲ ባይዱ 什么是抢占式调度
抢占式调度是一种操作系统调度方式,可以在任何时间中断正在执行的进程, 并将处理器分配给其他优先级更高的进程。
抢占式调度的优点和缺点
1 优点
抢占式调度对系统资源的影响
CPU
增加CPU占用率,降低响 应时间。
内存
增加内存占用,可能导致 内存碎片化。
磁盘
增加磁盘访问频率,影响 磁盘性能。
抢占式调度的安全性和可靠性
安全性
避免资源竞争和死锁问题。
可靠性
能够正确处理各种异常和错误情况。
提高系统响应速度和资源利用率,增强系统的可控性和稳定性。
短作业优先调度算法例题详解

短作业优先调度算法例题详解短作业优先调度算法例题详解什么是短作业优先调度算法?短作业优先调度算法是一种常见的进程调度算法,它的主要思想是优先调度执行当前剩余运行时间最短的作业。
在这种算法下,长时间作业的响应时间会相对较长,但是短时间作业的响应时间会更短。
算法原理短作业优先调度算法的原理是按照作业的执行时间来进行调度,优先选择执行时间较短的作业。
当一个作业到达时,操作系统会检查作业的执行时间,并将其与已有作业的执行时间进行比较,选择执行时间最短的作业进行调度。
算法实现以下是一个简单的短作业优先调度算法的例子:1.输入作业的数量和每个作业的执行时间。
2.按照作业的执行时间对作业进行排序,从执行时间最短的作业开始执行。
3.执行作业直到所有作业执行完毕。
例题解析假设有三个作业需要执行,它们的执行时间分别为5、2和8。
使用短作业优先调度算法对这些作业进行调度。
1.首先,按照作业的执行时间对作业进行排序,排序后的顺序为2、5和8。
2.执行时间最短的作业是2,因此首先执行该作业,剩下的两个作业的执行时间分别为5和8。
3.接下来,执行时间较短的作业是5,执行该作业后,剩下的作业的执行时间为8。
4.最后,执行剩下的唯一一个作业,执行时间为8。
根据以上步骤,最终的作业执行顺序为2、5和8。
优缺点分析短作业优先调度算法的优点是能够最大程度地缩短短时间作业的响应时间,提高系统的吞吐量。
然而,这种算法容易造成长时间作业的等待时间过长,可能会导致长时间作业的执行效率较低。
总结短作业优先调度算法是一种常见的进程调度算法,其核心原理是选择执行时间最短的作业进行调度。
通过对作业的排序和执行,可以最大程度地减少短时间作业的响应时间。
然而,这种算法也存在一些问题,如可能会导致长时间作业的等待时间过长。
因此,在实际应用中,需要根据具体情况选择合适的调度算法。
算法的应用场景短作业优先调度算法适用于作业的执行时间差异较大的情况。
在这种情况下,短时间作业可以迅速得到执行,提高系统的响应速度。
时间片轮转调度算法

// 时间片轮转调度算法#include <iostream>#include <cstdio>#include <cmath>#include <cstring>using namespace std;enum STATUS {RUN,READY,WAIT,FINISH};struct PCBNode{int processID; //进程IDSTATUS status; //进程状态int priorityNum; //优先数int reqTime; //总的需要运行时间int remainTime; //剩下需要运行时间int arriveTime; //进入就绪队列时间int startTime; //开始运行时间int finishTime; //结束运行时间int totalTime; //周转时间float weightTotalTime; //带权周转时间};struct QueueNode{int ID; //进程IDstruct QueueNode * next; //队列中下一个进程指针};struct LinkQueue{QueueNode *head;//队首};void Fcfs(LinkQueue& Q, int& totalTimeSum, int& weightTotalTimeSum,PCBNod e * ProcessT able);bool RR_Run(LinkQueue& Q,QueueNode* q, QueueNode* p, const int Roun d,int& currentTime,PCBNode * ProcessT able);//分配时间片给q所指进程,p为刚退出的进程void RoundRobin(LinkQueue& Q,const int Round, int& totalTimeSum, int& weightTotalTimeSum,PCBNode * ProcessT able);//时间片轮转调度,调用RR_Run(),时间片大小设为Roundvoid InitialQueue(LinkQueue& Q,PCBNode * ProcessT able,const int processnum );//初始化就绪队列void Input(PCBNode * ProcessT able, const int processnum);//从input.txt文件输入数据int main(){LinkQueue Q;//就绪队列Q.head = NULL;const int processnum = 16;//进程数const int Round = 1; //时间片大小int totalTimeSum = 0; //周转时间int WeightTotalTimeSum = 0;//带权周转时间PCBNode * ProcessT able=new PCBNode[processnum]; //进程表Input(ProcessT able, processnum);InitialQueue(Q, ProcessT able, processnum);RoundRobin(Q, Round, totalTimeSum,WeightTotalTimeSum,ProcessT able);cout < < "时间片轮调度的平均周转时间为: " < <totalTimeSum/processnum < <endl;cout < < "时间片轮调度的平均带权周转时间为: " < <WeightTotalTimeSum/processnum < <endl;Input(ProcessT able, processnum);InitialQueue(Q, ProcessT able, processnum);Fcfs(Q, totalTimeSum,WeightTotalTimeSum,ProcessT able);cout < < "先来先服务的平均周转时间为: " < <totalTimeSum/processnum < <endl;cout < < "先来先服务的平均带权周转时间为: " < <WeightTotalTimeSum/processnum < <endl;delete [] ProcessT able;return 0;}void RoundRobin(LinkQueue& Q,const int Round, int& totalTimeSum, int& weightTotalTimeSum,PCBNode * ProcessT able){totalTimeSum = 0; //总的周转时间weightTotalTimeSum = 0;//平均周转时间int currentTime = 0; //当前时间QueueNode* p;QueueNode* q;QueueNode* r;bool finish = false;//调用RR_Run()后,该进程是否已经做完退出p = Q.head;q = p-> next;while (q != NULL)//从队首开始依次分配时间片{do{cout < < "********************** " < <endl;cout < < "在时间片" < <(currentTime+1)/Round < < "内,活动进程为: " < <q-> ID < <endl;cout < < "进程" < <q-> ID < < " 现在需要的时间片为: " < <ProcessT able[q-> ID].remainTime < <endl;finish = RR_Run(Q, q, p, Round, currentTime, ProcessT a ble);//分配时间片给q进程cout < <endl;if (!finish)//若是进程在本时间片内做完,则跳出d o…while循环{if (q-> next == NULL){r = Q.head-> next;}else{r = q-> next;}}else //否则计算周转时间和带权周转时间{totalTimeSum += ProcessT able[q-> ID].totalTime;weightTotalTimeSum += ProcessT able[q-> ID].weightTotalTime;delete q; //从队列中删除q进程q = p;}}while (!finish && (ProcessT able[r-> ID].arriveTime > currentTime + Round));//下一个进程很晚才来,则继续给当前进程分配时间片p = q;q = q-> next;if (q == NULL && Q.head-> next!=NULL){p = Q.head;q = p-> next;}}delete Q.head;Q.head = NULL;}bool RR_Run(LinkQueue& Q,QueueNode* q, QueueNode* p, const int Roun d,int& currentTime,PCBNode * ProcessT able){if (ProcessT able[q-> ID].remainTime <= Round)//在此时间片内能够做完,之后退出进程调度{ProcessT able[q-> ID].finishTime = currentTime + ProcessT able[q-> ID].remainTime;ProcessT able[q-> ID].totalTime += ProcessT able[q-> ID].remainTime;ProcessT able[q-> ID].weightTotalTime = ProcessT able[q-> ID].totalTime/ProcessT able[q-> ID].reqTime;currentTime = ProcessT able[q-> ID].finishTime;p-> next = q-> next;cout < <endl;cout < < "进程" < <q-> ID < < "完成! " < <endl;return true;}else//此时间片内做不完{ProcessT able[q-> ID].remainTime = ProcessT able[q-> ID].remainTime - Round;ProcessT able[q-> ID].totalTime += Round;currentTime += Round;return false;}}void Fcfs(LinkQueue& Q, int& totalTimeSum, int& weightTotalTimeSum,PCBNod e * ProcessT able){totalTimeSum = 0;weightTotalTimeSum = 0;//平均周转时间QueueNode* p;QueueNode* q;p = Q.head-> next;if (p !=NULL ){ProcessT able[p-> ID].startTime = ProcessT able[p-> ID].arriveTime;ProcessT able[p-> ID].finishTime = ProcessT able[p-> ID].arriveTime + ProcessT able[p-> ID].reqTime;}for(q=p-> next; q!=NULL; q=q-> next){if (ProcessT able[q-> ID].arriveTime < ProcessT able[p-> ID].finishTime){ProcessT able[q-> ID].startTime = ProcessT able[p-> ID].finishTime;ProcessT able[q-> ID].finishTime = ProcessT able[p-> ID].finishTime + ProcessT able[q-> ID].reqTime;}else//下个进程到达时间较晚{ProcessT able[q-> ID].startTime = ProcessT able[q-> ID].arriveTime;ProcessT able[q-> ID].finishTime = ProcessT able[q-> ID].arriveTime + ProcessT able[q-> ID].reqTime;}p = q;}for(q=Q.head-> next; q!=NULL; q=q-> next){ProcessT able[q-> ID].totalTime = ProcessT able[q-> ID].finishTime - ProcessT able[q-> ID].arriveTime;ProcessT able[q-> ID].weightTotalTime = ProcessT able[q-> ID].totalTime/ProcessT able[q-> ID].reqTime;totalTimeSum += ProcessT able[q-> ID].totalTime;weightTotalTimeSum += ProcessT able[q-> ID].weightTotalTime;}int t = 0;for(q=Q.head-> next; q!=NULL; q=q-> next){cout < < "********************* " < <endl;while ( t <ProcessT able[q-> ID].finishTime ){cout < < "时刻" < <t < < ": 进程" < <q-> ID < < "活动" < <endl;t++;}if (q-> next != NULL){cout < < "时刻" < <t < < ": 进程" < <q-> ID < < "结束活动,开始下一个进程. " < <endl;cout < < "进程" < <q-> ID < < "的周转时间为: " < <ProcessT able[q-> ID].totalTime < <endl;cout < < "进程" < <q-> ID < < "的带权周转时间为: " < <ProcessT able[q-> ID].weightTotalTime < <endl < <endl;}else{cout < < "时刻" < <t < < ": 进程" < <q-> ID < < "结束活动. " < <endl < <endl;cout < < "进程" < <q-> ID < < "的周转时间为: " < <ProcessT able[q-> ID].totalTime < <endl;cout < < "进程" < <q-> ID < < "的带权周转时间为: " < <ProcessT able[q-> ID].weightTotalTime < <endl < <endl;}}cout < < "所有进程结束活动. " < <endl < <endl;p = Q.head;for(q=p-> next; q!=NULL; q=q-> next){delete p;p = q;}}void InitialQueue(LinkQueue& Q, PCBNode * ProcessT able,const int processn um){//初始化for (int i=0;i <processnum;i++){ProcessT able[i].processID=i;ProcessT able[i].reqTime=ProcessT able[i].remainTime;ProcessT able[i].finishTime=0;ProcessT able[i].startTime=0;ProcessT able[i].status=WAIT;ProcessT able[i].totalTime=0;ProcessT able[i].weightTotalTime=0;}Q.head = new QueueNode;Q.head-> next = NULL;QueueNode * p;QueueNode * q;for (i=0;i <processnum;i++){p = new QueueNode;p-> ID = i;p-> next = NULL;if (i == 0){Q.head-> next = p;}elseq-> next = p;q = p;}}void Input(PCBNode * ProcessT able, const int processnum){FILE *fp; //读入线程的相关内容if((fp=fopen( "input.txt ", "r "))==NULL){cout < < "can not open file! " < <endl;exit(0);}for(int i=0;i <processnum;i++){fscanf(fp, "%d %d %d ",&ProcessT able[i].arriveTime,&ProcessT able[i].remainTime,&ProcessT able[i].priorityNum);}fclose(fp);}建议输入数据:input.txt0 4 01 35 12 10 23 5 36 9 47 21 5 9 35 611 23 712 42 813 1 914 7 10 20 5 1123 3 1224 22 1325 31 1426 1 15。
操作系统第五版费祥林-课后习题答案参考

操作系统第五版费祥林-课后习题答案参考第二章处理器管理1.下列指令中哪些只能在核心态运行?(l)读时钟日期;(2)访管指令;(3)设时钟日期;(4)加载PSW; (5)置特殊寄存器:(6)改变存储器映象图;(7)启动I/O指令。
答:( 3 ) , ( 4 ) , ( 5 ) , ( 6 ) , ( 7 ) .2 假设有一种低级调度算法是让“最近使用处理器较少的进程”运行,试解释这种算法对“I/O 繁重”型作业有利,但并不是永远不受理“处理器繁重”型作业。
答:因为I/O繁忙型作业忙于I/O,所以它CPU 用得少,按调度策略能优先执行。
同样原因一个进程等待CPU 足够久时,由于它是“最近使用处理器较少的进程”,就能被优先调度,故不会饥饿。
3 并发进程之间有什么样的相互制约关系?下列日常生活中的活动是属哪种制约关系:(1)踢足球,(2)吃自助餐,(3)图书馆借书,(4)电视机生产流水线工序。
答:并发进程之间的基本相互制约关系有互斥和同步两种。
其中(1)、(3)为互斥问题.(2)、(4)为同步问题。
4 在按动态优先数调度进程的系统中,每个进程的优先数需定时重新计算。
在处理器不断地在进程之间交替的情况下,重新计算进程优先数的时间从何而来?答:许多操作系统重新计算进程的优先数在时钟中断处理例程中进行,由于中断是随机碰到哪个进程,就插入哪个进程中运行处理程序,并把处理时间记在这个进程的账上。
5 若后备作业队列中等待运行的同时有三个作业J1 、J2、J3 ,已知它们各自的运行时间为a 、b 、c,且满足a < b <c,试证明采用短作业优先算法调度能获得最小平均作业周转时间。
答:采用短作业优先算法调度时,三个作业的总周转时间为:Tl = = a + ( a +b ) + ( a + b + c ) = 3a + 2b + c ①若不按短作业优先算法调度,不失一般性,设调度次序为:J2 、J1 、J3 。
则三个作业的总周转时间为:T2=b+(b+a ) +(b+a + c ) = 3b + 2a + c ②令②-①式得到:T2 - Tl = b- a> 0可见,采用短作业优先算法调度才能获得最小平均作业周转时间。
第三版操作系统第3章习题

操作系统第三章总复习题一、单选题1、进程调度又称低级调度,其主要功能是( D )。
A.选择一个作业调入内存B.选择一个主存中的进程调出到外存C.选择一个外存中的进程调入到主存D.将一个就绪的进程投入到运行2、若进程P 一旦被唤醒就能够投入运行,系统可能为( D )。
A.分时系统,进程P 的优先级最高B.抢占调度方式,就绪队列上的所有进程的优先级皆比P 的低C.就绪队列为空队列D.抢占调度方式,P 的优先级高于当期运行的进程。
3、一个进程P 被唤醒后,( D )。
A.P 就占有了CPU。
B.P 的PCB 被移到就绪队列的队首。
C.P 的优先级肯定最高D.P 的状态变成就绪4、若当前运行进程()后,系统将会执行进程调度原语。
A 执行了一个转移指令B 要求增加主存空间,经系统调用银行家算法进行测算认为是安全的。
C 执行了一条I/O 指令要求输入数据。
D 执行程序期间发生了I/O 完成中断。
5、当系统中()时,系统将不会执行进程调度原语。
A.一个新进程被创建B.当前进程执行了P 操作。
C.在非抢占调度中,进程A 正在运行而进程B 恰好被唤醒。
D.分时系统中时间片用完。
6、在分时系统中,若当期运行的进程连续获得了两个时间片,原因可能是()。
A 该进程的优先级最高B 就绪队列为空C 该进程最早进入就绪队列D 该进程是一个短进程7、实时系统中采用的调度算法可以有如下几种:1、非抢占优先权调度算法2、立即抢占优先权调度算法3、时间片轮转调度算法4、基于时钟中断抢占的优先权调度算法按实时要求的严格程度由低到高的顺序()。
A 1-3-2-4B 3-1-4-2C 3-1-2-4D 1-3-4-28、三种主要类型的OS 中都必须配置的调度()。
A 作业调度B 中级调度C 低级调度D I/O 调度9、设系统中n 个进程并发,共同竞争资源X,且每个进程都需要m 个X 资源,为使该系统不会发生死锁,资源X 最少要有( C )个。
单片机 优先级调度算法

在单片机系统中,优先级调度算法用于确定在有多个任务同时运行时,哪个任务具有更高的优先级,应该先执行。
这在实时系统和嵌入式系统中非常重要,因为这些系统通常需要对任务的响应时间和执行顺序进行精确控制。
以下是一些常见的单片机优先级调度算法:1. 固定优先级调度(Fixed Priority Scheduling):- 每个任务被分配一个固定的优先级,由开发者在设计时确定。
- 任务按照它们的优先级进行调度,具有更高优先级的任务将在具有较低优先级的任务之前执行。
2. 轮转法(Round Robin Scheduling):- 每个任务都有一个时间片(time slice)或执行时间的最大限制。
- 任务按照轮流的方式执行,每个任务在分配的时间片内运行,然后切换到下一个任务。
- 如果一个任务在其时间片结束之前未完成,它将被放回队列,等待下一个时间片。
3. 最短剩余时间优先(Shortest Remaining Time First,SRTF):- 每个任务都有一个估计的执行时间。
- 在每个调度点,选择剩余执行时间最短的任务来执行。
- 这是一种抢占式调度算法,可能会在执行过程中切换到更紧急的任务。
4. 最早截止期限优先(Earliest Deadline First,EDF):- 每个任务都有一个截止期限。
- 在每个调度点,选择截止期限最早的任务来执行。
- 这是一种抢占式调度算法,适用于实时系统,确保截止期限更早的任务先执行。
5. 多级队列调度(Multilevel Queue Scheduling):- 将任务分为多个队列,每个队列有不同的优先级。
- 任务按照其优先级放置在相应的队列中,每个队列可以采用不同的调度算法。
- 任务可以在队列之间移动,例如,根据它们的执行历史或其他因素。
选择合适的调度算法取决于系统的需求和性能要求。
实时系统通常需要更为精确和可预测的调度,而通用用途的系统可能更关注性能和资源利用率。
rr时间片轮转算法例题

时间片轮转算法(Round Robin,简称RR)是一种简单而常用的进程调度算法。
该算法按照固定的时间片长度将CPU时间分配给各个进程,当时间片用完时,进程被放到队列末尾,等待下一次调度。
下面是一个简单的RR算法的例子:
假设有三个进程A、B和C,它们的执行时间分别为10、20和30个时间单位。
每个进程在完成其执行时间后结束。
首先,将所有进程的执行时间累加起来得到总执行时间:A + B + C = 10 + 20 + 30 = 60个时间单位。
然后,计算每个进程的执行时间占总执行时间的比例:A = 10/60 = 1/6,B = 20/60 = 1/3,C = 30/60 = 1/2。
接下来,按照比例分配时间片。
假设时间片的长度为X个时间单位,则:
A的执行时间为X * (1/6) = X/6个时间单位;
B的执行时间为X * (1/3) = X/3个时间单位;
C的执行时间为X * (1/2) = X/2个时间单位。
假设时间片长度为5个时间单位,则:
A在第一个时间片内完成,总共需要5/6个时间单位;
B在第二个时间片内完成,总共需要5/3个时间单位;
C在第三个时间片内完成,总共需要5/2个时间单位。
最终,每个进程的完成时间和剩余CPU时间是:
A完成时间为5/6 + 5/3 = 15/6个时间单位;
B完成时间为5/3 + 5/2 = 25/6个时间单位;
C完成时间为5/2 + 5/6 = 40/6个时间单位。
需要注意的是,RR算法可能会导致某些进程等待较长时间,因此在实际应用中需要根据实际情况选择合适的调度算法。
操作系统常用调度算法

操作系统常⽤调度算法在操作系统中存在多种调度算法,其中有的调度算法适⽤于作业调度,有的调度算法适⽤于进程调度,有的调度算法两者都适⽤。
下⾯介绍⼏种常⽤的调度算法。
先来先服务(FCFS)调度算法FCFS调度算法是⼀种最简单的调度算法,该调度算法既可以⽤于作业调度也可以⽤于进程调度。
在作业调度中,算法每次从后备作业队列中选择最先进⼊该队列的⼀个或⼏个作业,将它们调⼊内存,分配必要的资源,创建进程并放⼊就绪队列。
在进程调度中,FCFS调度算法每次从就绪队列中选择最先进⼊该队列的进程,将处理机分配给它,使之投⼊运⾏,直到完成或因某种原因⽽阻塞时才释放处理机。
下⾯通过⼀个实例来说明FCFS调度算法的性能。
假设系统中有4个作业,它们的提交时间分别是8、8.4、8.8、9,运⾏时间依次是2、1、0.5、0.2,系统⾤⽤FCFS调度算法,这组作业的平均等待时间、平均周转时间和平均带权周转时间见表2-3。
表2-3 FCFS调度算法的性能作业号提交时间运⾏时间开始时间等待时间完成时间周转时间带权周转时间18280102128.4110 1.611 2.6 2.638.80.511 2.211.5 2.7 5.4490.211.5 2.511.7 2.713.5平均等待时间 t = (0+1.6+2.2+2.5)/4=1.575平均周转时间 T = (2+2.6+2.7+2.7)/4=2.5平均带权周转时间 W = (1+2.6+5.牡13.5)/4=5.625FCFS调度算法属于不可剥夺算法。
从表⾯上看,它对所有作业都是公平的,但若⼀个长作业先到达系统,就会使后⾯许多短作业等待很长时间,因此它不能作为分时系统和实时系统的主要调度策略。
但它常被结合在其他调度策略中使⽤。
例如,在使⽤优先级作为调度策略的系统中,往往对多个具有相同优先级的进程按FCFS原则处理。
FCFS调度算法的特点是算法简单,但效率低;对长作业⽐较有利,但对短作业不利(相对SJF和⾼响应⽐);有利于CPU繁忙型作业,⽽不利于I/O繁忙型作业。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学 号: 课 程 设 计 题 目 进程调度模拟设计——时间片轮转、强占式短进程优先算法
学 院 计算机科学与技术学院
专 业 班 级 姓 名 指导教师 吴利军
2013 年 1 月 16 日 课程设计任务书 学生姓名: 指导教师:吴利军 工作单位: 计算机科学与技术学院 题 目: 进程调度模拟设计——时间片轮转、强占式短进程优先算法 初始条件: 1.预备内容:阅读操作系统的处理机管理章节内容,对进程调度的功能以及进程调度算法有深入的理解。 2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写
等具体要求) 1.模拟进程调度,能够处理以下的情形: ⑴ 能够选择不同的调度算法(要求中给出的调度算法); ⑵ 能够输入进程的基本信息,如进程名、到达时间和运行时间等; ⑶ 根据选择的调度算法显示进程调度队列; ⑷ 根据选择的调度算法计算平均周转时间和平均带权周转时间。 2.设计报告内容应说明: ⑴ 需求分析; ⑵ 功能设计(数据结构及模块说明); ⑶ 开发平台及源程序的主要部分; ⑷ 测试用例,运行结果与运行情况分析; ⑸ 自我评价与总结: i)你认为你完成的设计哪些地方做得比较好或比较出色; ii)什么地方做得不太好,以后如何改正; iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训); iv)完成本题是否有其他方法(如果有,简要说明该方法);
时间安排: 设计安排一周:周1、周2:完成程序分析及设计。 周2、周3:完成程序调试及测试。 周4、周5:验收、撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,一律按0分记) 指导教师签名: 年 月 日 系主任(或责任教师)签名: 年 月 日 进程调度模拟设计 时间片轮转、强占式短进程优先算法 一、需求分析 本次课程设计需要通过设计一个模拟进程调度的系统,来实现进程调度过程的模拟,对进程调度的功能以及进程调度的算法有更加深层次的理解。 时间片轮转法的基本思路是每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。这样让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。 在批处理为主的系统中,如果采用FCFS方式进程作业调度,虽然系统开销小,算法简单,但是,如果估计执行时间很短的作业时在那些长作业的后面到达系统的话,则必须等待长作业执行完成之后才有机会获得执行。这将造成不必要的等待和不公平,最短作业优先法就是选择那些估计需要执行时间最短的作业投入执行,为它们创建进程和分配资源。直观上说,采用最短作业优先的调度算法,可使得系统在同一时间内处理的作业个数最多,从而吞吐量也就大于其它调度方式。 按照需求有以下条件: 进程PCB(包含进程名、到达时间、预计运行时间等) 调度算法(时间片轮转、强占式短进程优先) 为完成这两种算法的调度模拟,需要用高级语言编程完成模拟操作,能够处理以下的情形: (1)能够选择不同的调度算法(要求中给出的调度算法) (2)能够输入进程的基本信息,如进程名、到达时间和运行时间等 (3)根据选择的调度算法显示进程调度队列 (4)根据选择的调度算法计算平均周转时间和平均带权周转时间 该设计中的进程调度模拟系统在使用时,用户可以输入各进程信息(包含进程名、到达时间、估计运行时间);输入完毕确认后,可选择两种调度算法中的一种执行,查看结果可得到相应算法的调度序列,每个进程的到达时间、预计运行时间、开始时间、结束时间和周转时间、带权周转时间,以及平均周转时间和平均带权周转时间。 二、功能设计
2.1 进程信息的描述和实现 此次课程设计中,进程作为基本数据处理单元,需要对进程的基本信息进行相关的描述。进程的基本信息包括进程进程名、到达的时间、预计的进程运行时间、进程开始运行时间、进程仍需运行的时间、进程完成的时间、进程运行的次数等。在此,定义一个类来抽象进程。并在此基础上进行其他操作。数据结构方案声明如下: class ProcePcb { public : ProcePcb (string name,int sub,int exe,int id) : pro_name(name),time_submit(sub),time_exe(exe),pro_id(id), time_start(0),time_end(0),time_wait(0),pro_state(READY),time_left(exe), time_turn(0),time_aver(0.0){} //默认构造函数 ProcePcb () : pro_name (string(" ")), time_submit(0),time_exe(0),pro_id(-1), time_end(0),time_start(0),time_wait(0),pro_state(READY),time_left(0), time_turn(0),time_aver(0.0) {} //Getters and Setters string getPro_name () { return pro_name ;} int getTime_submit () { return time_submit ;} int getTime_exe () { return time_exe ;} int getPro_id () { return pro_id ;} int getTime_start () { return time_start ; } int getTime_wait () { return time_start ; } int getPro_state () { return pro_state ;} int getTime_left () { return time_left ;} int getTime_turn () { return time_turn ;} int getTime_aver () { return time_aver ;} void setTime_start (int start) { time_start = start ; } //设置开始时间 void setTime_left (int left) { time_left = left ;} void setTime_end (int end) { time_end = end ; } //设置结束时间 void setPro_state (int state) { pro_state = state ;} //设置进程的状态
//..打印进程的信息 void PrintPcbInfo () ; // //..进程执行模拟 bool ProceExe(int) ; //参数为时间单位,返回CPU是否执行完毕
//内部逻辑计算 包括周转时间以及带权周转时间的计算 void CalTimeLogic() ;
protected: //进程的名字 string pro_name ; //提交时间--用十进制封装 int time_submit ; //从时间的1开始计时 //进程所需的运行时间 int time_exe ; //进程ID -- 系统生成 int pro_id ; //开始执行的时间 int time_start ; //结束的时间 int time_end ; //等待的时间 int time_wait ; //进程的状态 (就绪,执行,完成) int pro_state ; //...上下文封装 int time_left ; //还需多少时间单位,初始化为所需的执行时间 //周转时间 int time_turn ; //带权周转时间 float time_aver ; } ; 2.2 调度算法的描述和实现 进程基本信息所构成的模块作为基本单元,并且相关调度算法的侧重进程基本信息点不同,所以要根据其调度算法的特点来结合基本信息进行对应的设计。此次课程设计要求的调度算法描述如下:
2.2.1 时间片轮转调度算法 时间片轮转法的中心思想在于将CPU的运行划分为一个个时间片,然后将这些时间片平均分配给已经准备就绪的进程,在一个时间片内只允许一个进程占用处理器。如果当前进程运行结束则时间片终止。这样可以较公平的分配处理器运行时间,使每个进程都可以得到处理。
2.2.2 强占式短进程优先调度算法 对强占式短进程优先调度算法而言,其本质特征便是按进程的预计运行时间长短进行排序,先执行短进程。若内存中运行的进程优先级比就绪队列中的某进程优先级低(即运行的进程预计运行时间比就绪队列中的某进程长),此运行的进程让出内存并进入就绪队列,优先级更高的短进程强占内存资源并运行直到结束或者遇到优先级更高的进程强占为止。
2.2.3 模块说明: class CPUModel //CPU功能模块的封装 { public : CPUModel () :pcbnum(0),idCount(0),allturn(0),allaver(0.0) {} //从用户界面获取进程 void GetPcb (pcbList &) ; //..CPU开始执行程序 void ExeProce(pcbList &) ; //时间片轮转法模拟程序 void RRModel(pcbList&) ; //不能改变原队列 //抢占式短进程优先 void SJF_Grab(sjfList) ; //..获取当前时刻之前的最短进程在队列中的标号 int GetTheSP(sjfList ,int) ; //队列为排序之后的队列 //..获取下一个进程ID int GetNextId() ; //打印就绪队列中的进程的信息 void PrintList(pcbList) ; int getPcbnum () { return pcbnum ; }
//... bool IsProComing(int) ; //..当前时刻时是否有新的进程到达
//...将就绪队列按提交时间排序 void SortTheList(sjfList) ;
bool IsOver(sjfList) ; //是否所有的进程都执行完毕 private : //进程数量 int pcbnum ; int idCount ; //进程ID计数 int allturn ; //总周转时间 float allaver ; //总带权周转时间