前言
提示:了解进程优先级算法和时间片轮转算法的基本原理再进行代码学习。
提示:以下是本篇文章正文内容,下面案例可供参考
一、进程优先级调度算法
-
基本原理(知识背景):
按照进程的优先级高低来进行调度,使高优先级进程优先得到处理机的调度算法称为优先级调度算法(即优先级数值大的先进行调度)。但在许多采用优先级调度算法的系统中,通常使用动态优先级。一个进程的优先级不是固定的,可能会随许多因素的变化而变化,例如,进程的等待时间、已使用的处理机时间或其他资源的使用情况。 -
优先级调度算法又可分为下述两种:
①非抢占式的优先级调度算法。一旦某个高优先级的进程得到处理机,就一直运行下去,直到由于其自身的原因(任务完成或等待事件)而主动让出处理机,才让另一个高优先级进程运行。
②抢占式的优先级调度算法。任何时刻都严格按照优先级高的进程在处理机上运行的原则进行调度,或者说,在处理机上运行的进程永远是就绪进程队列中优先级最高的进程。在进程运行过程中,一旦有另一个优先级更高的进程出现(如一个高优先级的等待状态进程因事件的到来而成为就绪状态),进程调度程序就迫使原运行进程让出处理机给更高优先级的进程使用,或称为抢占处理机。 -
例题(思路)
(1)非抢占式
各进程到达就绪队列的时间、需要的运行时间、进程优先数如下表所示。使用非抢占式的优先级调度算法,分析进程运行情况。(优先数越大,优先级越高)调度过程:正在处理的进程处理结束,接下来每次调度时选择当前已到达且优先级最高的进程。
-
注:以下括号内表示当前处于就绪队列的进程
0时刻(P1):只有P1到达,P1上处理机。 7时刻(P2、P3,P4):P1运行完成主动放弃处理机,其余进程都已到达,P3优先级最高,P3上处理机。8时刻(P2、P4):P3完成,P2P4优先级相同,由于P2先到达,因此P2优先上处理机。
—————————————
(2)抢占式
各进程到达就绪队列的时间、需要的运行时间、进程优先数如下表所示。使用抢占式的优先级调度算法,分析进程运行情况。(优先数越大,优先级越高)
调度过程:每次调度时选择当前已到达且优先级最高的进程。当前进程主动放弃处理机时发生调度。就是在运行进程的过程中,放弃当前进行,去进行优先级高的进程。
—————————————
0时刻(P1):只有P1到达,P1上处理机。
2时刻(P2):P2到达就绪队列,优先级比P1更高,发生抢占。P1回到就绪队列,P2上处理机。
4时刻(P1、P3):P3到达,优先级比P2更高,P2回到就绪队列,P3抢占处理机。
5时刻(P1、P2、P4):P3完成,主动释放处理机,同时,P4也到达,由于P2比P4更先进入就绪队列,因此选择P2上处理机
7时刻(P1P4):P2完成,就绪队列只剩P1、P4,P4上处理机。11时刻(P1):P4完成,P1上处理机
16时刻():P1完成,所有进程均完成
—————————————
二、时间片轮转调度算法
-
基本原理(知识背景):
根据先来先服务的原则,将需要执行的所有进程按照到达时间的大小排成一个升序的序列,每次都给一个进程同样大小的时间片,在这个时间片内如果进程执行结束了,那么把进程从进程队列中删去,如果进程没有结束,那么把该进程停止然后改为等待状态,放到进程队列的尾部,直到所有的进程都已执行完毕 -
进程的切换
时间片够用:意思就是在该时间片内,进程可以运行至结束,进程运行结束之后,将进程从进程队列中删除,然后启动新的时间片
时间片不够用:意思是在该时间片内,进程只能完成它的一部分任务,在时间片用完之后,将进程的状态改为等待状态,将进程放到进程队列的尾部,等待cpu的调用。 -
关于时间片大小的选择
时间片过小,则进程频繁切换,会造成cpu资源的浪费
时间片过大,则轮转调度算法就退化成了先来先服务算法。 -
例题(思路)
1.完成下列表格
2.解析:
进程处理的流程(P=1) :
三、核心代码(注意:优先级调度算法是采用非抢占算法)
1.引入库
代码如下(示例):
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
///PCB控制块信息
typedef struct PCB
{
int id; ///进程id
int priority; ///进程优先级
int status; ///进程状态 0:就绪 1:运行
int ptime; ///进程到达时间 // 上一个进程的完成时间 = 这个进程的开始时间
int start; ///开始运行时间
int finish; ///完成时刻时间 //完成时间 = 开始时间 + 运行时间
int runtime; ///进程运行时间
bool operator< (const PCB &t) const
{
if( ptime != t. ptime) return ptime < t. ptime;
return runtime < t.runtime;
};
}PCB;
///就绪队列
typedef struct ReadyNode
{
PCB data; ///已就绪的进程id
ReadyNode *next; ///用next来指向下一个进程
};
PCB pcb[100]; ///结构体PCB数组,用来存放已经创建PCB控制块,即处于就绪状态
int N = 0; ///记录当前已经创建的进程数目
typedef struct ReadyNode *Ready; ///定义一个 ReadyNode 指针方便后续的应用
const int M = 100; //最长100个时间单位
PCB pcb_list[100]; //进程列表
vector<PCB> table[M]; //进程时刻表
queue<PCB> que; //进程队列
int n,t,q,sjp; //进程数,总计时,固定时间片,运转时间片
int max_time; //最大时间
///判断进程是否已创建,如果存在则返回 1,否则返回 0.
int isOrNot(int num)
{
for(int i = 0;i < N;i++)
{
if(num == pcb