操作系统原理实验:使用动态优先权的进程调度算法的模拟

该博客介绍了操作系统实验中使用动态优先权的进程调度算法模拟,重点在于多级反馈队列(MLFQ)的实现。通过实验,作者探讨了进程控制块(PCB)的结构,优先级变化规则,以及如何处理优先级相同的进程。代码部分强调了使用链表和迭代器处理STL容器中的元素删除,以避免效率损失。实验结果显示了不同数量进程的调度情况。
摘要由CSDN通过智能技术生成

实验目的

通过动态优先权算法的模拟加深进程概念和进程调度过程的理解,并学习撰写规范的科学研究报告。

实验内容与要求

1.对N个进程采用动态优先权算法的进程调度;
2.每个用来标识进程的进程控制块PCB用结构描述,包括以下字段:进程标识数ID,进程优先数PRIORITY,进程已占用的CPU时间CPUTIME,进程还需占用的CPU时间ALLTIME,进程状态STATE等。
3.优先数改变的原则:进程在就绪队列中呆一个时间片,优先数增加1,进程每运行一个时间片优先数减3。
4.设置调度前的初始状态。
5.将每个时间片内的进程情况显示出来。

实验原理

模拟通过MLFQ(多级反馈队列)算法实现的动态优先权进程调度。根据上面的实验要求,结合实际计算机系统的情况,适当改写算法规则。
调度的规则是:
对两个任务A、B,
(1)如果A的优先级更高,则运行A,暂停B。
(2)如果优先级相同,则按FCFS的原则轮流运行。
(3)当系统接到新的任务时,该任务总被赋予最高优先级。
(4)一个任务每使用一个时间片,其优先级降低3级。
(5)一个任务每暂停一个时间片,其优先级增加1级。
另外,在实际的计算机系统中,由于我们无法得知一个进程何时结束,因此在进程控制块(PCB)中的“还需占用的CPU时间”一项不会被调度器考虑。
本模拟程序中,优先级分为4级。0级最高,3级最低。更低优先级的队列的时间片更长。每次都在最高优先级的队列中按照FCFS算法选择一个任务在此核心上运行。只有更高的优先级队列全为空时,一个较低优先级的队列的任务才会被运行。
每隔1 ms输出每个进程的信息,包括PID、已运行的毫秒数和进程状态(运行 / 就绪)。
本实验是对在单个核心上的进程调度的简单模拟。由于篇幅所限,未模拟进程请求IO等情形。
进程的初始状态通过随机算法来生成。输出进程信息时,可以通过注释或取消注释相应代码来设置按PID排序或按优先级排序。

代码

横向长度较长。建议复制到IDE中,最大化窗口后查看。

#include<cstdio>
#include<random>
#include<chrono>
#include<vector>
#include<algorithm>
#include<list>
#pragma warning(disable:4996)

const unsigned np = 64; //Number of processes.
const ptrdiff_t pmax = 3; //The maximum of priority.
const char* const process_state[] = {
    "Running", "Ready" };
std::uniform_int_distribution<int> upid(1, 9999); std::uniform_int_distribution<ptrdiff_t> upr(0, pmax);
std::uniform_int_distribution<unsigned> utime(1, 1000); std::default_random_engine dre;

//Process controllling block.
struct PCB {
    int pid; ptrdiff_t priority; unsigned runtime, runtime_max, last_alloc_time, state; };
std::vector<std::list<PCB*>> q; const std::list<PCB*> empty_list; PCB p[np], * r; std::vector<unsigned> out;
bool busy; //Whether this CPU core is busy.
unsigned n = np; //The number of processes remaining.
unsigned last_sched_ms; //last_sched_ms is the global elapsed time when last time slice allocating on a willing-to-run process occurred.
unsigned ms; //ms is the global runtime.
unsigned ts[pmax + 1]; //ts is the time slice of each queue. ms is the global runtime (ms) after the scheduler is activated.

//Print the info of a process.
inline void print(const PCB* const p) {
   
	printf("%4d | %12u | %16u | %8lld | %s\n", p->pid, p->runtime, p->runtime_max, p->priority, process_state[p->state]);
}

//inline bool output_cmp(const int& x, const int& y) { return p[x].pid < p[y].pid; }
inline bool output_cmp(const unsigned& x, const unsigned& y) {
    return p[x].priority < p[y
  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(1)用C语言来实现对N个进程采用动态优先权优先算法进程调度。 (2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段: •••• 进程标识数 ID。 •••• 进程优先数 PRIORITY,并规定优先数越大的进程,其优先权越高。 •••• 进程已占用的CPU时间CPUTIME。 •••• 进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。•••• 进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,将进入阻塞状态。 •••• 进程被阻塞的时间BLOCKTIME,表示已足赛的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。 •••• 进程状态START。 •••• 队列指针NEXT,用来将PCB排成队列。 (3)优先数改变的原则: •••进程在就绪队列中呆一个时间片,优先数加1。 •••进程每运行一个时间片,优先数减3。 (4)假设在调度前,系统中有5个进程,它们的初始状态如下: ID 0 1 2 3 4 PRIORITY 9 38 30 29 0 CPUTIME 0 0 0 0 0 ALLTIME 3 3 6 3 4 STARTBLOCK 2 -1 -1 -1 -1 BLOCKTIME 3 0 0 0 0 STATE READY READY READY READY READY (5)为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下: RUNNING PROG:i READY-QUEUE:->id1->id2 BLOCK-QUEUE:->id3->id4 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ID 0 1 2 3 4 PRIORITY P0 P1 P2 P3 P4 CUPTIME C0 C1 C2 C3 C4 ALLTIME A0 A1 A2 A3 A4 STARTBLOCK T0 T1 T2 T3 T4 BLOCKTIME B0 B1 B2 B3 B4 STATE S0 S1 S2 S3 S4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值