题目与要求
题目名称:进程调度。
内容要求:编写算法,模拟实现进程调度算法,包括非抢占短进程优先算法、可抢占优先权调度算法及多级反馈队列调度算法。
具体实现要求如下:(不局限下 述情况,在工作量不缩减的情况下,可行设计实现过程。) (1)调度所需的进程参数(即 PCB,包括进程名、到达时间、要求服务时间、 优先级等)由输入产生(可手工输入或随机产生); (2)进行算法评价,计算平均周转时间; (3)输出调度结果,输出算法评价指标。
一、概述
1.1内容介绍
本课程设计旨在模拟实现操作系统中的三种典型进程调度算法[1]:非抢占短进程优先(NPSPP)算法、可抢占优先权调度(PPSA)算法以及多级反馈队列(MLFQ)调度算法。进程调度是操作系统中的核心任务之一,负责在多个进程之间合理分配CPU资源,提高系统效率和用户体验。本课程设计要求编写相应的算法代码,生成并调度进程,最终输出调度结果和评价指标(如平均周转时间),以评估各算法的性能。
1.2难点分析
进程参数的生成和管理:生成进程参数(包括进程名、到达时间、要求服务时间、优先级等)并保证其合理性和随机性。维护进程控制块(PCB)结构,并确保其状态在调度过程中实时更新。
调度算法的实现:实现非抢占短进程优先算法时,需确保找到已到达且服务时间最短的进程。实现抢占式优先权调度算法时,需要考虑进程的优先级变化及抢占机制。实现多级反馈队列调度算法时,需要处理不同优先级队列之间的进程调度和时间片分配[2]。
算法评价:计算各算法的平均周转时间,评价其性能。比较不同算法的调度结果,分析其优劣。
二、基本概念与原理
本次课程设计我们的核心概念是进程调度。进程调度是操作系统中的一项关键功能,负责决定在什么时间由哪个进程使用CPU。调度的目标是提高系统效率和用户满意度。在本次课程设计中,涉及三种典型进程调度算法:非抢占短进程优先(NPSPP)算法、可抢占优先权调度(PPSA)算法以及多级反馈队列(MLFQ)调度算法。
非抢占短进程优先(NPSPP)算法:选择服务时间最短的进程执行,直到该进程完成。其优点是能最小化平均等待时间和周转时间,但可能导致长进程的“饥饿”现象。
可抢占优先权调度(PPSA)算法:该算法根据进程的优先级进行调度,高优先级进程可以抢占低优先级进程的CPU使用权。其优点是保证了高优先级进程的及时响应,但可能导致低优先级进程的“饥饿”[3]。
多级反馈队列(MLFQ)调度算法:该算法将进程分配到不同优先级的队列中,优先级越高的队列时间片越短。若进程未能在当前队列时间片内完成,则被移动到下一个低优先级队列。其优点是综合考虑了响应时间和周转时间,但实现复杂度较高。
三、需求分析
本课程设计的主要任务是实现和比较三种经典的进程调度算法:非抢占短进程优先调度算法(NPSPP),抢占式优先级调度算法(PPSA),以及多级反馈队列调度算法(MLFQ)。在此基础上,生成并管理一组进程参数,并对各个调度算法的性能进行评估,最终输出调度结果和相关评价指标。具体需求分析如下:
3.1功能需求
3.1.1进程生成与初始化
通过程序随机生成一组进程参数。进程参数包括进程ID、到达时间、服务时间(执行时间)、优先级等。生成的进程列表应包含多个进程实例,每个实例包含其参数信息
3.1.2调度算法的实现
非抢占短进程优先调度算法(NPSPP):实现一个非抢占式调度算法,按照进程的服务时间长度进行调度,即服务时间最短的进程优先执行。抢占式优先级调度算法(PPSA):实现一个抢占式调度算法,按照进程的优先级进行调度,即优先级最高的进程优先执行。当一个更高优先级的进程到达时,正在运行的进程会被抢占。多级反馈队列调度算法(MLFQ):实现一个多级反馈队列调度算法,通过多个队列对进程进行分级管理,不同队列有不同的时间片长度。高优先级队列时间片较短,低优先级队列时间片较长,随着进程在各级队列间的迁移,实现动态调整优先级[4]。
3.1.3调度过程的模拟与输出
对每个调度算法,模拟进程调度过程,记录每个进程的开始时间、完成时间等。输出调度结果,包括每个进程的开始时间、完成时间、周转时间、等待时间等。
3.1.4算法性能评价
平均周转时间计算:计算每种调度算法的平均周转时间(所有进程的周转时间之和除以进程总数)[5]。比较与输出:比较不同调度算法的平均周转时间,并将结果输出,帮助用户了解不同算法的性能差异。
3.1.5用户交互界面
提供一个简单的用户界面,用户可以通过选择菜单选项,执行不同的调度算法,查看调度结果和评价指标。提供退出选项,允许用户随时退出程序。
3.2性能需求
高效性:设计的调度算法应在合理的时间内完成调度,尤其是当进程数量较多时,算法的性能不应显著下降[6]。
可扩展性:程序应具备良好的扩展性,允许将来添加新的调度算法或修改现有算法而不需要对整体架构进行大幅度调整。
3.3非功能需求
用户友好性:程序的用户界面应简洁明了,用户能够方便地选择不同的功能选项,查看调度结果和评价指标。
可维护性:代码应结构清晰,具有良好的注释和文档,便于后期的维护和修改。
四、总体设计
4.1系统总体功能模块设计
4.1.1进程生成与初始化模块
功能:通过程序随机生成一组进程参数。
输入:进程总数(由用户输入)。
输出:包含进程ID、到达时间、服务时间、优先级等信息的进程列表。
4.1.2调度算法模块
功能:实现三种经典的进程调度算法(NPSPP, PPSA, MLFQ)。
输入:进程列表。
输出:调度过程的模拟和调度结果。
4.1.3调度过程模拟与输出模块
功能:模拟调度过程并记录每个进程的开始时间、完成时间等信息。
输入:进程列表。
输出:调度结果,包括每个进程的开始时间、完成时间、周转时间、等待时间等。
4.1.4算法性能评价模块
功能:计算每种调度算法的平均周转时间,比较不同调度算法的平均周转时间并输出结果。
输入:调度结果。
输出:平均周转时间的比较结果。
4.1.5用户交互界面模块
功能:提供一个简单的用户界面,允许用户选择不同的调度算法,查看调度结果和评价指标,并允许用户退出程序。
输入:用户选择的菜单选项。
输出:对应的功能执行结果。
4.1.6大体模块图
本课程设计大体设计模块图如图4.1所示。
图4.1 大体模块图
4.2实现方法和主要技术路线
4.2.1进程生成与初始化模块
使用 initializeProcesses() 函数,通过随机数生成器生成进程的到达时间、服务时间和优先级。
通过用户输入确定进程总数,并根据总数生成相应数量的进程。
4.2.2调度算法模块
非抢占短进程优先调度算法(NPSPP)使用 NPSPP() 函数实现。根据到达时间对进程进行排序,然后选择服务时间最短的进程进行调度。
抢占式优先级调度算法(PPSA)使用 PPSA() 函数实现。根据到达时间和优先级对进程进行排序,当一个更高优先级的进程到达时,正在运行的进程会被抢占。
多级反馈队列调度算法(MLFQ)使用 MLFQ() 函数实现。通过多个队列对进程进行分级管理,不同队列有不同的时间片长度,随着进程在各级队列间的迁移,实现动态调整优先级。
4.2.3调度过程模拟与输出模块
通过在调度算法函数中记录每个进程的开始时间、完成时间、周转时间和带权周转时间。使用 printProcessState() 函数输出当前进程的状态。
4.2.4算法性能评价模块
使用 calculateAverageTurnaroundTime() 函数计算每种调度算法的平均周转时间。使用 printAverageTurnaroundTimes() 函数比较不同调度算法的平均周转时间并输出结果。
4.2.5用户交互界面模块
提供一个菜单界面,允许用户选择执行不同的调度算法,查看调度结果和评价指标,或者退出程序。使用 main() 函数实现用户交互界面,通过循环结构实现菜单选择功能。
五、详细设计
5.1进程初始化模块
使用函数initializeProcesses(int numProcesses): 初始化进程数据,随机生成到达时间和CPU服务时间等参数。如图5.1所示。
图5.1 进程初始化流程图
5.2非抢占短进程优先算法(NPSJF)模块
主要函数:NPSPP(): 实现非抢占短进程优先算法,计算每个进程的完成时间、周转时间和带权周转时间。如图5.2所示。
图5.2 非抢占短进程优先算法流程图
5.3抢占式优先级调度算法(PPSA)模块
主要函数:PPSA(): 实现抢占式优先级调度算法,根据优先级调度进程,并计算每个进程的完成时间、周转时间和带权周转时间。如图5.3所示。
图5.3 抢占式优先级调度算法流程图
5.4多级反馈队列(MLFQ)模块
主要函数:MLFQ(): 实现多级反馈队列算法,根据进程的动态优先级调度进程,并计算每个进程的完成时间、周转时间和带权周转时间。如图5.4所示。
图5.4 多级反馈队列算法流程图
5.5算法评价模块
主要函数:CATT(): 计算并打印平均周转时间和平均带权周转时间。如图5.5所示。
图5.5 算法评价流程图
六、软件测试
6.1功能测试
验证每个调度算法的正确性,通过随机生成的进程参数进行测试[7]。表明采用的测试方法及测试用例,展示测试效果。
6.1.1功能测试用例
输入5个进程,分别测试非抢占短进程优先调度算法、抢占式优先级调度算法和多级反馈队列调度算法,检查每个算法的调度结果和平均周转时间。
6.1.2功能测试测试效果
所有功能测试用例均通过,调度结果与预期一致。如图6.1、图6.2、图6.3、图6.4所示
图6.1 程序开始界面测试图
图6.2 非抢占短进程优先调度算法测试图
图6.3 抢占式优先级调度算法测试图
图6.4 多级反馈队列调度算法测试图
6.2性能测试
验证各个调度算法在处理大量进程时的性能和效率。
6.2.1性能测试用例
输入99个进程,分别测试三种调度算法的性能和效率。
6.2.2性能测试测试效果
性能测试显示,三种调度算法在处理大规模进程时的性能有所差异,但均能在合理时间内完成调度。如图6.5、图6.6、图6.7所示。
图6.5 性能测试过程图
图6.6 性能测试结果图
图6.7性能测试时间结果图
参考文献
[1]汤小丹.计算机操作系统(3版).西安:西安电子科技大学出版社,2007(91).
[2]肖建明,张向利.一种改进的时间片轮转调度算法[J].计算机应用,2005.
[3]黄斌.多级反馈队列调度策略在Linux中的应用和实现[J].计算机工程,2004.
[4]李亚玲,鲁建丽,贾子璇.计算机操作系统调度方法探究[J].决策探索(中),2020,(02):80.
[5]田露飞.常见进程调度算法的比较与改进[J].计算机光盘软件与应用,2014,17(16):46-47.
[6]杨恒胜.操作系统调度机制的研究[D].北京交通大学,2012.
[7]白红义.常用进程调度算法的分析与评价[J].数字技术与应用,2010,(10):99+101.
附录1代码
#include <iostream>
#include <cstdlib>
#include <ctime>
#include<windows.h>
#include <queue>
#include <vector>
using namespace std;
const int NUM_QUEUES = 3; // 多级反馈队列的数量
const int TIME_SLICES[NUM_QUEUES] = { 2, 4, 8 }; // 每个队列的时间片
typedef struct PCB
{
char name; //进程名
char state; //进程状态
int arr_time; //到达时间
int fin_time; //完成时间
int rest_time; //剩余时间
int CPU_time; //服务时间
int run_time; //已运行时间
int Tr; //周转时间
float Tw; //带权周转时间
int priority;
struct PCB* next;
int index; //对应的 process[] 的下标
} PCB;
struct AlgorithmResult {
string name;
double avgTurnaroundTime;
};//用于后面的算法评价
PCB process[100]; // 假设最多 100 个进程
PCB initialProcess[100]; // 保存初始进程数据
int N = 5; // 全局变量,进程总数
void initializeProcesses(int numProcesses) {
srand(time(0)); // 使用当前时间作为随机数种子
for (int i = 0; i < numProcesses; i++) {
process[i].name = 'A' + i; // 给每个进程命名为 A, B, C, ...
process[i].state = 'W'; // 初始状态为等待态
process[i].arr_time = rand() % 100; // 随机到达时间在 0 到 99 之间
process[i].CPU_time = rand() % 20 + 1; // 随机服务时间在 1 到 20 之间
process[i].run_time = 0; // 初始运行时间为 0
process[i].rest_time = process[i].CPU_time; // 初始剩余时间等于服务时间
process[i].fin_time = 0; // 初始完成时间为 0
process[i].Tr = 0; // 初始周转时间为 0
process[i].Tw = 0.0; // 初始带权周转时间为 0.0
process[i].priority = rand() % 10 + 1;
process[i].next = nullptr; // 初始下一个指针为空
process[i].index = i; // 对应的 process 数组下标
}
for (int i = 0; i < N; i++) {
initialProcess[i] = process[i];
}
}
bool compareByTurnaroundTime(const AlgorithmResult& a, const AlgorithmResult& b) {
return a.avgTurnaroundTime < b.avgTurnaroundTime;
}//自定义一个比较器
PCB* linknode(int num, PCB* bef) {
PCB* newNode = new PCB;
newNode->name = process[num].name;
newNode->state = process[num].state;
newNode->arr_time = process[num].arr_time;
newNode->fin_time = process[num].fin_time;
newNode->rest_time = process[num].rest_time;
newNode->CPU_time = process[num].CPU_time;
newNode->run_time = process[num].run_time;
newNode->Tr = process[num].Tr;
newNode->Tw = process[num].Tw;
newNode->next = nullptr;
newNode->index = process[num].index;
bef->next = newNode;
return newNode;
}
void initializeProcesses() {
srand(time(0)); // 使用当前时间作为随机数种子
for (int i = 0; i < N; i++) {
process[i].name = 'A' + i; // 给每个进程命名为 A, B, C, ...
process[i].state = 'W'; // 初始状态为等待态
process[i].arr_time = rand() % 100; // 随机到达时间在 0 到 99 之间
process[i].CPU_time = rand() % 20 + 1; // 随机服务时间在 1 到 20 之间
process[i].run_time = 0; // 初始运行时间为 0
process[i].rest_time = process[i].CPU_time; // 初始剩余时间等于服务时间
process[i].fin_time = 0; // 初始完成时间为 0
process[i].Tr = 0; // 初始周转时间为 0
process[i].Tw = 0.0; // 初始带权周转时间为 0.0
process[i].priority = rand() % 10 + 1;
process[i].next = nullptr; // 初始下一个指针为空
process[i].index = i; // 对应的 process 数组下标
}
for (int i = 0; i < N; i++) {
initialProcess[i] = process[i];
}
}
void sortProcessesByArrivalTime() {
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
if (process[i].arr_time > process[j].arr_time) {
PCB temp = process[i];
process[i] = process[j];
process[j] = temp;
}
}
}
}
void printProcessState(PCB* temp) {
PCB* p = temp;
for (int i = 0; i < N; i++) {
cout << "当前进程状态:" << endl;
cout << "进程 " << p->name;
cout << ": 到达时间=" << p->arr_time;
cout << ", 服务时间=" << p->CPU_time;
cout << ", 运行时间=" << p->run_time;
cout << ", 剩余时间=" << p->rest_time;
cout << ", 完成时间=" << p->fin_time;
cout << ", 状态=" << p->state << endl;;
cout << "---------------------------------" << endl;
p = p->next;
}
}
void p1rintProcessState() {
cout << "当前进程状态:" << endl;
for (int i = 0; i < N; i++) {
cout << "进程 " << process[i].name
<< ": 到达时间=" << process[i].arr_time
<< ", 服务时间=" << process[i].CPU_time
<< ", 运行时间=" << process[i].run_time
<< ", 剩余时间=" << process[i].rest_time
<< ", 完成时间=" << process[i].fin_time
<< ", 周转时间=" << process[i].Tr
<< ", 带权周转时间=" << process[i].Tw
<< ", 优先级=" << process[i].priority
// << ", 索引=" << process[i].index
<< ", 状态=" << process[i].state << endl;
}
cout << "---------------------------------" << endl;
}
void restoreProcesses() {
for (int i = 0; i < N; i++) {
process[i] = initialProcess[i];
}
}
void deleteNode(int index, PCB* th) {
PCB* head = th;
PCB* temp = head;
PCB* prev = nullptr;
// 如果头节点本身是要删除的节点
if (temp != nullptr && temp->index == index) {
head = temp->next; // 更改头指针
delete temp; // 释放旧头节点
return;
}
// 搜索要删除的节点
while (temp != nullptr && temp->index != index) {
/*cout << "预期:" << index;
cout << "当前:" << temp->index;*/
prev = temp;
temp = temp->next;
}
// 如果没有找到该节点
if (temp == nullptr) {
cout << "节点不存在,无法删除" << endl;
return;
}
// 从链表中移除节点
prev->next = temp->next;
delete temp;
N--;
}
void CATT() {//Calculate average turnover time
double sumTr = 0;
for (int i = 0; i < N; i++) {
sumTr += process[i].Tr;
}
cout << "平均周转时间:" << sumTr / N << endl;
}
double calculateAverageTurnaroundTime() {//返回值形式的周转时间平均值
double sumTr = 0;
for (int i = 0; i < N; i++) {
sumTr += process[i].Tr;
}
return sumTr / N;
}
void NPSPP() {//Non preemptive short process priority algorithm非抢占短进程优先算法
cout << "非抢占短进程优先算法" << endl;
restoreProcesses();
p1rintProcessState();
sortProcessesByArrivalTime();
int t = 0, n = N;
PCB* head, * tail;
PCB* p = new PCB;
int num = 0;
p->name = process[num].name;
p->state = process[num].state;
p->arr_time = process[num].arr_time;
p->fin_time = process[num].fin_time;
p->rest_time = process[num].rest_time;
p->CPU_time = process[num].CPU_time;
p->run_time = process[num].run_time;
p->Tr = process[num].Tr;
p->Tw = process[num].Tw;
p->next = nullptr;
p->index = num;
head = p;
tail = p;
int completedProcesses = 0;
for (int i = 1; i < n; i++) {
tail = linknode(i, tail);
}
while (completedProcesses < N) {
// 找到已经到达且状态为等待的进程中服务时间最短的进程
int shortestJobIndex = -1;
int minCPUTime = INT_MAX;
for (int i = 0; i < N; i++) {
if (process[i].arr_time <= t && process[i].state == 'W' && process[i].CPU_time < minCPUTime) {
shortestJobIndex = i;
minCPUTime = process[i].CPU_time;
}
}
// 如果找到这样的进程
if (shortestJobIndex != -1) {
cout << "@@@@@@@@@" << endl;
PCB& currentProcess = process[shortestJobIndex];
t += currentProcess.CPU_time; // 当前时间增加当前进程的服务时间
currentProcess.run_time = currentProcess.CPU_time;
currentProcess.rest_time = 0;
currentProcess.fin_time = t;
currentProcess.state = 'F';
currentProcess.Tr = currentProcess.fin_time - currentProcess.arr_time;
currentProcess.Tw = (float)currentProcess.Tr / currentProcess.CPU_time;
completedProcesses++;
p1rintProcessState();
}
else {
// 如果没有进程到达则时间增加1
t++;
}
cout << "当前时间:" << t << endl;
}
CATT();
}
void PPSA() { // Preemptive Priority Scheduling Algorithm
cout << "抢占式优先级调度算法" << endl;
restoreProcesses();
p1rintProcessState();
sortProcessesByArrivalTime();
int t = 0;
int completedProcesses = 0;
int currentProcessIndex = -1;
while (completedProcesses < N) {
cout << "当前时间:" << t << endl;
// 找到已经到达且状态为等待的进程中优先级最高的进程
int highestPriorityIndex = -1;
int highestPriority = INT_MAX;
for (int i = 0; i < N; i++) {
if (process[i].arr_time <= t && process[i].state != 'F' && process[i].priority < highestPriority) {
highestPriority = process[i].priority;
highestPriorityIndex = i;
}
}
// 如果找到这样的进程
if (highestPriorityIndex != -1) {
PCB& highestPriorityProcess = process[highestPriorityIndex];
if (currentProcessIndex != highestPriorityIndex) {
// 如果当前进程不是优先级最高的进程,切换到优先级最高的进程
cout << "进行抢占,进程名:" << process[highestPriorityIndex].name << endl;
currentProcessIndex = highestPriorityIndex;
}
PCB& currentProcess = process[currentProcessIndex];
t++; // 增加时间
currentProcess.run_time++; // 增加运行时间
currentProcess.rest_time--; // 减少剩余时间
if (currentProcess.rest_time == 0) {
// 如果当前进程完成
currentProcess.fin_time = t;
currentProcess.state = 'F';
currentProcess.Tr = currentProcess.fin_time - currentProcess.arr_time;
currentProcess.Tw = (float)currentProcess.Tr / currentProcess.CPU_time;
completedProcesses++;
currentProcessIndex = -1; // 重置当前进程索引
p1rintProcessState();
}
}
else {
// 如果没有进程到达则时间增加1
t++;
}
}
// 打印所有进程的最终状态
cout << "所有进程完成后的最终状态:" << endl;
p1rintProcessState();
CATT();
}
void MLFQ() {
cout << "多级反馈队列调度算法" << endl;
restoreProcesses();
p1rintProcessState();
sortProcessesByArrivalTime();
vector<queue<PCB*>> queues(NUM_QUEUES);
int t = 0;
int completedProcesses = 0;
int currentQueue = 0;
PCB* currentProcess = nullptr;
// 初始化队列,将所有进程放入第一个队列
for (int i = 0; i < N; i++) {
queues[0].push(&process[i]);
}
while (completedProcesses < N) {
cout << "当前时间:" << t << endl;
if (currentProcess == nullptr) {
// 找到一个非空队列
for (int i = 0; i < NUM_QUEUES; i++) {
if (!queues[i].empty()) {
currentQueue = i;
currentProcess = queues[i].front();
queues[i].pop();
break;
}
}
}
if (currentProcess->arr_time <= t && currentProcess->state != 'F' && currentProcess != nullptr) {
int timeSlice = TIME_SLICES[currentQueue];
int runTime = min(timeSlice, currentProcess->rest_time);
t += runTime;
currentProcess->run_time += runTime;
currentProcess->rest_time -= runTime;
if (currentProcess->rest_time == 0) {
// 进程完成
currentProcess->fin_time = t;
currentProcess->state = 'F';
currentProcess->Tr = currentProcess->fin_time - currentProcess->arr_time;
currentProcess->Tw = (float)currentProcess->Tr / currentProcess->CPU_time;
completedProcesses++;
currentProcess = nullptr;
p1rintProcessState();
}
else {
// 进程未完成,移动到下一个队列
cout << "进程" << currentProcess->name << "未完成,移动到下一个队列" << endl;
if (currentQueue < NUM_QUEUES - 1) {
queues[currentQueue + 1].push(currentProcess);
}
else {
queues[currentQueue].push(currentProcess);
}
currentProcess = nullptr;
}
}
else {
// 如果没有进程到达则时间增加1
t++;
}
}
CATT();
}
void printAverageTurnaroundTimes() {
PCB originalProcess[100];
for (int i = 0; i < N; i++) {
originalProcess[i] = process[i];
}
vector<AlgorithmResult> results;//用vector定义结构体数组
restoreProcesses();
NPSPP();
results.push_back({ "非抢占短进程优先算法", calculateAverageTurnaroundTime() });
restoreProcesses();
PPSA();
results.push_back({ "抢占式优先级调度算法", calculateAverageTurnaroundTime() });
restoreProcesses();
MLFQ();
results.push_back({ "多级反馈队列调度算法", calculateAverageTurnaroundTime() });
sort(results.begin(), results.end(), compareByTurnaroundTime);//排个序
cout << endl;
cout << endl;
cout << "平均周转时间排序:" << endl;
for (const auto& result : results) {
cout << result.name << ": " << result.avgTurnaroundTime << endl;
}
cout << endl;
for (int i = 0; i < N; i++) {
process[i] = originalProcess[i];
}
}
int main() {
do {
cout << "请输入进程总数 (1-100): ";
cin >> N;
if (N < 1 || N > 100) {
cout << "进程总数必须在 1 到 100 之间,请重新输入。" << endl;
}
} while (N < 1 || N > 100);
initializeProcesses(N);
int num = -1;
while (true) {
cout << "---------------------------------" << endl;
cout << " 进程调度" << "算法演示" << endl;
cout << " 非抢占短进程优先算法请输入1" << endl;
cout << " 可抢占优先权调度算法请输入2" << endl;
cout << " 多级反馈队列调度算法请输入3" << endl;
cout << " 进行算法评价请输入4" << endl;
cout << " 换一组数据请输入9" << endl;
cout << " 退出请输入0" << endl;
cout << "---------------------------------" << endl;
cin >> num;
switch (num) {
case 1:
NPSPP();
break;
case 2:
PPSA();
break;
case 3:
MLFQ();
break;
case 4:
printAverageTurnaroundTimes();
break;
case 9:
initializeProcesses();
Sleep(800);
cout << "---------------------------------" << endl;
cout << "@@@进程数据更新完成@@@" << endl;
cout << "---------------------------------" << endl;
break;
case 0:
return 0;
}
}
}