实验内容:进程的优先级算法和时间片段轮转算法(C++实现)


前言

提示:了解进程优先级算法和时间片轮转算法的基本原理再进行代码学习。


提示:以下是本篇文章正文内容,下面案例可供参考

一、进程优先级调度算法

  1. 基本原理(知识背景):
    按照进程的优先级高低来进行调度,使高优先级进程优先得到处理机的调度算法称为优先级调度算法(即优先级数值大的先进行调度)。但在许多采用优先级调度算法的系统中,通常使用动态优先级。一个进程的优先级不是固定的,可能会随许多因素的变化而变化,例如,进程的等待时间、已使用的处理机时间或其他资源的使用情况。

  2. 优先级调度算法又可分为下述两种:
    非抢占式的优先级调度算法。一旦某个高优先级的进程得到处理机,就一直运行下去,直到由于其自身的原因(任务完成或等待事件)而主动让出处理机,才让另一个高优先级进程运行。
    抢占式的优先级调度算法。任何时刻都严格按照优先级高的进程在处理机上运行的原则进行调度,或者说,在处理机上运行的进程永远是就绪进程队列中优先级最高的进程。在进程运行过程中,一旦有另一个优先级更高的进程出现(如一个高优先级的等待状态进程因事件的到来而成为就绪状态),进程调度程序就迫使原运行进程让出处理机给更高优先级的进程使用,或称为抢占处理机。

  3. 例题(思路)
    (1)非抢占式
    各进程到达就绪队列的时间、需要的运行时间、进程优先数如下表所示。使用非抢占式的优先级调度算法,分析进程运行情况。(优先数越大,优先级越高)

    调度过程:正在处理的进程处理结束,接下来每次调度时选择当前已到达且优先级最高的进程。

    在这里插入图片描述

  4. 注:以下括号内表示当前处于就绪队列的进程
    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完成,所有进程均完成

    —————————————
    在这里插入图片描述

二、时间片轮转调度算法

  1. 基本原理(知识背景):
    根据先来先服务的原则,将需要执行的所有进程按照到达时间的大小排成一个升序的序列,每次都给一个进程同样大小的时间片,在这个时间片内如果进程执行结束了,那么把进程从进程队列中删去,如果进程没有结束,那么把该进程停止然后改为等待状态,放到进程队列的尾部,直到所有的进程都已执行完毕

  2. 进程的切换
    时间片够用:意思就是在该时间片内,进程可以运行至结束,进程运行结束之后,将进程从进程队列中删除,然后启动新的时间片
    时间片不够用:意思是在该时间片内,进程只能完成它的一部分任务,在时间片用完之后,将进程的状态改为等待状态,将进程放到进程队列的尾部,等待cpu的调用。

  3. 关于时间片大小的选择
    时间片过小,则进程频繁切换,会造成cpu资源的浪费
    时间片过大,则轮转调度算法就退化成了先来先服务算法。

  4. 例题(思路)
    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 
  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
1、设计一个程序实现基于优先数的时间轮转调度算法调度处理器。 2、假定系统有5个进程,每个进程用一个进程控制块PCB开代表,进程控制块的结构 /*例如一组进程如下表: 进程名 A B C D E F G H J K L M 到达时间 0 1 2 3 6 8 12 12 12 18 25 25 服务时间 6 4 10 5 1 2 5 10 4 3 15 8 */ PCB:进程名 指针 到达时间 要求运行时间 已运行时间 优先数 进程状态 其中: 进程名:作为进程的标识。 指针:进程按顺序排成循环链表,用指针指出下一个进程进程控制块首地址,最后一个进程中的指针指出第一个进程进程控制块首地址。 要求运行时间:假设进程需要运行的单位时间数。 已运行时间:假设进程已经运行的单位时间数,初值为0。 状态:可假设有两种状态,就绪状态和结束状态。进程的初始状态都为就绪状态。 3、每次运行所设计的处理器调度程序调度进程之前,为每个进程任意确定它的要求运行时间。 4、此程序是模拟处理器调度,因此,被选中的进程并不实际启动运行,而是执行 已运行时间+1 来模拟进程的一次运行,表示进程已经运行过一个单位时间。 .5、在所设计的程序中应有显示或打印语句,能显示或打印每次被选中的进程名以及运行一次后进程队列的变化。 6、为进程任意确定要求运行时间,运行所设计的处理器调度程序,显示或打印逐次被选中进程进程名以及进程控制块的动态变化过程。 7、设有一个就绪队列,就绪进程按优先数(优先数范围0-100)由小到大排列(优先数越小,级别越高)。当某一进程运行完一个时间片后,其优先级应下调(如优先数加2或3)。
好的,下面是一个同时支持按优先级时间轮转进程调度算法的 C++ 程序。程序中使用了两个优先级队列(一个按照优先级排列,一个按照时间轮转顺序排列),并且使用了一个计时器来模拟时间轮转。程序会不断从两个队列中取出优先级最高的进程,然后执行一个时间片。如果进程还未运行完毕,那么会将其重新插入到队列中,否则将其从队列中删除。 ```c++ #include <iostream> #include <queue> #include <vector> using namespace std; struct Process { int pid; // 进程 ID int priority; // 优先级 int burst_time; // 还需要运行的时间 int runtime; // 已经运行的时间 // 构造函数 Process(int pid, int priority, int burst_time) : pid(pid) , priority(priority) , burst_time(burst_time) , runtime(0) { } // 运行一个时间片,返回是否已经完成 bool run(int quantum) { runtime += quantum; burst_time -= quantum; return burst_time <= 0; } // 重载小于运算符,用于优先级队列排序 bool operator<(const Process& other) const { if (priority == other.priority) { return pid > other.pid; } return priority < other.priority; } }; int main() { // 创建两个优先级队列,一个按照优先级排序,一个按照时间轮转顺序排序 priority_queue<Process> pq_priority; priority_queue<Process, vector<Process>, function<bool(const Process&, const Process&)>> pq_rr( [](const Process& a, const Process& b) { return a.runtime > b.runtime; }); // 添加一些进程到队列中 pq_priority.emplace(1, 2, 20); pq_priority.emplace(2, 1, 30); pq_priority.emplace(3, 3, 15); pq_priority.emplace(4, 2, 25); // 定义一个计时器,用于模拟时间轮转 int timer = 0; // 循环运行进程,直到队列为空 while (!pq_priority.empty() || !pq_rr.empty()) { // 从两个队列中取出优先级最高的进程 Process current; if (pq_priority.empty()) { current = pq_rr.top(); pq_rr.pop(); } else if (pq_rr.empty()) { current = pq_priority.top(); pq_priority.pop(); } else if (pq_priority.top() < pq_rr.top()) { current = pq_priority.top(); pq_priority.pop(); } else { current = pq_rr.top(); pq_rr.pop(); } // 运行一个时间片 bool completed = current.run(10); timer += 10; if (!completed) { // 进程还未完成,根据已运行时间重新插入到队列中 pq_rr.push(current); } // 打印当前进程信息 cout << "Time: " << timer << "ms, "; cout << "PID: " << current.pid << ", "; cout << "Priority: " << current.priority << ", "; cout << "Burst Time: " << current.burst_time << endl; } return 0; } ``` 希望这个程序可以帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值