实验目的
通过动态优先权算法的模拟加深进程概念和进程调度过程的理解,并学习撰写规范的科学研究报告。
实验内容与要求
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