常见的调度算法
- 先来先服务调度算法
- 最短作业优先调度算法
- 高响应比优先调度算法
- 最高优先级调度算法
- 时间片轮转调度算法
- 多级反馈队列调度算法
- ... ...
数据结构
typedef struct program { char name[20]; int running_time; int enter_time; int priority; int done_time; //用于时间片轮转 int copyRunning_time; //用于时间片轮转 int start_time; program* next; } Program; typedef struct programQueue { program* firstProg; program* LastProg; int size; } programQueue;
先来先服务调度算法
顾名思义,先来后到,每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或被阻塞,才会继续从队列中选择第一个进程接着运行。但是当一个长作业先运行了,那么后面的短作业等待的时间就会很长,不利于短作业。FCFS 对长作业有利,适用于 CPU 繁忙型作业的系统,而不适用于 I/O 繁忙型作业的系统。
算法模拟思路:
- 首先将输入的进程放入一个进程数组中,然后根据进程的到达时间进行排序,将最先到达的进程放入进程就绪队列中。
- 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,并将在此进程执行期间到达的进程依次加入进程就绪队列。
- 如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。
算法模拟:
//FCFS先来先服务算法 void FCFS(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); //按照进入顺序排序 programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; sum_T_time += T_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_QT_time += QT_time; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { EnterQueue(queue, &pro[pronum]); pronum++; } } printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); }
最短作业优先调度算法
最短作业优先调度算法会优先选择运行时间最短的进程来运行,这有助于提高系统的吞吐量。这显然对长作业不利,很容易造成一种极端现象。比如,一个长作业在就绪队列等待运行,而这个就绪队列有非常多的短作业,那么就会使得长作业不断的往后推,周转时间变长,致使长作业长期不会被运行。
算法模拟思路:
- 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
- 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,设置一个变量记录此进程执行过程中所有到达的进程。
- 将这些到达的进程进行排序,按照进程服务时间的大小。然后将排序好的进程数组中的进程依次加入进程队列。(只排当前进程执行期间到达的进程)
- 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。
算法模拟:
//短作业优先算法 void SJF(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; int pre = pronum; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pronum++; } } sortWithLongth(pro, pre, pronum);//将到达的进程按照服务时间排序 for (int i = pre; i < pronum; i++) { //将进程链入队列 EnterQueue(queue, &pro[i]); } pre = pronum; printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / num); }
最高优先级调度算法
进程的优先级可以分为,静态优先级或动态优先级:
- 静态优先级:创建进程时候,就已经确定了优先级了,然后整个运行时间优先级都不会变化;
- 动态优先级:根据进程的动态变化调整优先级,比如如果进程运行时间增加,则降低其优先级,如果进程等待时间(就绪队列的等待时间)增加,则升高其优先级,也就是随着时间的推移增加等待进程的优先级。
该算法也有两种处理优先级高的方法,非抢占式和抢占式:
- 非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程。
- 抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行。
但是依然有缺点,可能会导致低优先级的进程永远不会运行
算法模拟思路:
- 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
- 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,设置一个变量记录此进程执行过程中所有到达的进程。
- 将这些到达的进程进行排序,按照进程优先权排序(权值小的先入)。然后将排序好的进程数组中的进程依次加入进程队列。(只排当前进程执行期间到达的进程)
- 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。
算法模拟:
//优先权高者优先(HPF) void HPF(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; int pre = pronum; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pronum++; } } sortWithPriority(pro, pre, pronum);//将到达的进程按照服务时间排序 for (int i = pre; i < pronum; i++) { //将进程链入队列 EnterQueue(queue, &pro[i]); } pre = pronum; printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); }
时间片轮转调度算法
每个进程被分配一个时间段,称为时间片,即允许该进程在该时间段中运行。如果时间片用完,进程还在运行,那么将会把此进程从 CPU 释放出来,并把 CPU 分配另外一个进程;如果该进程在时间片结束前阻塞或结束,则 CPU 立即进行切换;如果时间片设得太短会导致过多的进程上下文切换,降低了 CPU 效率;如果设得太长又可能引起对短作业进程的响应时间变长。
算法模拟思路:
- 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
- 当队列不空时,从队头取出一个进程来执行。此时分两种情况:①如果当前进程的剩余服务时间不大于时间片大小,说明此次将会将这个进程执 行完毕,在此进程执行过程中到达的进程需要添加到进程就绪队列中,这时就可以输出 此进程执行完毕②如果当前进程的剩余服务时间大于时间片大小,还需将此进程执行过程中到达 的进程需要添加到进程就绪队列中,然后此进程的剩余服务时间减少时间片大小,此进 程重新进入进程就绪队列
- 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列
算法模拟:
//时间片轮转(RR) void RR(program pro[], int num) { printf("请输入时间片大小"); int timeslice; scanf("%d", ×lice); printf("进程 到达时间 服务时间 进入时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); pro[0].start_time = pro[0].enter_time; EnterQueue(queue, &pro[0]); int time = 0; int pronum = 1; float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); // 从队列中取出头节点 if (time < curpro->enter_time) time = curpro->enter_time; if (timeslice >= curpro->running_time) { // 如果剩余时间小于时间片 则此任务完成 for (int tt = time; tt <= time + curpro->running_time && pronum < num; tt++) { // 模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pro[pronum].start_time = tt; EnterQueue(queue, &pro[pronum]); pronum++; } } time += curpro->running_time; curpro->running_time = 0; curpro->done_time = time; int T_time = curpro->done_time - curpro->start_time; float QT_time = T_time / (curpro->copyRunning_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; printf("%s\t%d\t%d\t %d\t %d\t %d\t %.2f\n", curpro->name, curpro->enter_time, curpro->copyRunning_time, curpro->start_time, curpro->done_time, T_time, QT_time); if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 pro[pronum].start_time = pro[pronum].enter_time; EnterQueue(queue, &pro[pronum]); pronum++; } continue; } for (int tt = time; tt <= time + timeslice && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pro[pronum].start_time = tt; EnterQueue(queue, &pro[pronum]); pronum++; } } time += timeslice; curpro->running_time -= timeslice; EnterQueue(queue, curpro); //当前程序未完成 继续添加到队列中 if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 pro[pronum].start_time = pro[pronum].enter_time; EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); }
完整代码:
我们分三个文件进行操作,当然大家也可以把三个文件按顺序放在一个文件里面进行操作
course.h: 结构体的包含以及函数的声明
course.cpp: 函数的具体实现
test.cpp: 主函数用于调用其余文件函数
course.h:
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<malloc.h> #include<string.h> #include<stdlib.h> typedef struct program { char name[20]; int running_time; int enter_time; int priority; int done_time; //用于时间片轮转 int copyRunning_time; //用于时间片轮转 int start_time; program* next; } Program; typedef struct programQueue { program* firstProg; program* LastProg; int size; } programQueue; //初始化 void Queueinit(programQueue* queue); //打印 void print(program pro[], int num); //打印队列 void printQueue(programQueue* queue); //加入进程队列 void EnterQueue(programQueue* queue, program* pro); //查询 program* poll(programQueue* queue); //输入 void inputProgram(program pro[], int num); //根据时间排序 void sortWithEnterTime(program pro[], int num); //FCFS先来先服务算法 void FCFS(program pro[], int num); //根据长度排序 void sortWithLongth(program pro[], int start, int end); //短作业优先算法 void SJF(program pro[], int num); //根据优先级排列 void sortWithPriority(program pro[], int start, int end); //优先权高者优先(HPF) void HPF(program pro[], int num); //时间片轮转(RR) void RR(program pro[], int num); //选择菜单 void choiceMenu();
course.cpp:
#define _CRT_SECURE_NO_WARNINGS 1 #include "course.h" //初始化 void Queueinit(programQueue* queue) { if (queue == NULL) { return; } queue->size = 0; queue->LastProg = (program*)malloc(sizeof(program)); queue->firstProg = queue->LastProg; } //打印 void print(program pro[], int num) { for (int i = 0; i < num; i++) { printf("%d ", pro[i].enter_time); } } //打印输出队列 void printQueue(programQueue* queue) { program* p = queue->firstProg->next; while (p != NULL) { printf("%s ", p->name); p = p->next; } printf("\n"); } //加入进程队列 void EnterQueue(programQueue* queue, program* pro) { queue->LastProg->next = (program*)malloc(sizeof(program)); queue->LastProg = queue->LastProg->next; queue->LastProg->enter_time = pro->enter_time; memcpy(queue->LastProg->name, pro->name, sizeof(pro->name)); queue->LastProg->priority = pro->priority; queue->LastProg->running_time = pro->running_time; queue->LastProg->copyRunning_time = pro->copyRunning_time; queue->LastProg->start_time = pro->start_time; queue->size++; } //查询 program* poll(programQueue* queue) { program* temp = queue->firstProg->next; if (temp == queue->LastProg) { queue->LastProg = queue->firstProg; queue->size--; return temp; } queue->firstProg->next = queue->firstProg->next->next; queue->size--; return temp; } //输入 void inputProgram(program pro[], int num) { for (int i = 0; i < num; i++) { program prog; printf("请输入第%d个进程的名字,到达时间,服务时间,优先级\n", i + 1); scanf("%s", prog.name); scanf("%d", &prog.enter_time); scanf("%d", &prog.running_time); prog.copyRunning_time = prog.running_time; scanf("%d", &prog.priority); pro[i] = prog; } } //根据时间排序 void sortWithEnterTime(program pro[], int num) { for (int i = 1; i < num; i++) { for (int j = 0; j < num - i; j++) { if (pro[j].enter_time > pro[j + 1].enter_time) { program temp = pro[j]; pro[j] = pro[j + 1]; pro[j + 1] = temp; } } } } //FCFS先来先服务算法 void FCFS(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); //按照进入顺序排序 programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; sum_T_time += T_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_QT_time += QT_time; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { EnterQueue(queue, &pro[pronum]); pronum++; } } printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); } //根据长度排序 void sortWithLongth(program pro[], int start, int end) { int len = end - start; if (len == 1) return; for (int i = 1; i < len; i++) { for (int j = start; j < end - i; j++) { if (pro[j].running_time > pro[j + 1].running_time) { program temp = pro[j]; pro[j] = pro[j + 1]; pro[j + 1] = temp; } } } } //短作业优先算法 void SJF(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; int pre = pronum; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pronum++; } } sortWithLongth(pro, pre, pronum);//将到达的进程按照服务时间排序 for (int i = pre; i < pronum; i++) { //将进程链入队列 EnterQueue(queue, &pro[i]); } pre = pronum; printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / num); } //根据优先级排列 void sortWithPriority(program pro[], int start, int end) { int len = end - start; if (len == 1) return; for (int i = 1; i < len; i++) { for (int j = start; j < end - i; j++) { if (pro[j].priority > pro[j + 1].priority) { program temp = pro[j]; pro[j] = pro[j + 1]; pro[j + 1] = temp; } } } } //优先权高者优先(HPF) void HPF(program pro[], int num) { printf("进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); EnterQueue(queue, &pro[0]); int time = pro[0].enter_time; int pronum = 1; //记录当前的进程 float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); //从进程队列中取出进程 if (time < curpro->enter_time) time = curpro->enter_time; int done_time = time + curpro->running_time; int T_time = done_time - curpro->enter_time; float QT_time = T_time / (curpro->running_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; int pre = pronum; for (int tt = time; tt <= done_time && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pronum++; } } sortWithPriority(pro, pre, pronum);//将到达的进程按照服务时间排序 for (int i = pre; i < pronum; i++) { //将进程链入队列 EnterQueue(queue, &pro[i]); } pre = pronum; printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time); time += curpro->running_time; if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); } //时间片轮转(RR) void RR(program pro[], int num) { printf("请输入时间片大小"); int timeslice; scanf("%d", ×lice); printf("进程 到达时间 服务时间 进入时间 完成时间 周转时间 带权周转时间\n"); sortWithEnterTime(pro, num); programQueue* queue = (programQueue*)malloc(sizeof(programQueue)); Queueinit(queue); pro[0].start_time = pro[0].enter_time; EnterQueue(queue, &pro[0]); int time = 0; int pronum = 1; float sum_T_time = 0, sum_QT_time = 0; while (queue->size > 0) { program* curpro = poll(queue); // 从队列中取出头节点 if (time < curpro->enter_time) time = curpro->enter_time; if (timeslice >= curpro->running_time) { // 如果剩余时间小于时间片 则此任务完成 for (int tt = time; tt <= time + curpro->running_time && pronum < num; tt++) { // 模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pro[pronum].start_time = tt; EnterQueue(queue, &pro[pronum]); pronum++; } } time += curpro->running_time; curpro->running_time = 0; curpro->done_time = time; int T_time = curpro->done_time - curpro->start_time; float QT_time = T_time / (curpro->copyRunning_time + 0.0); sum_T_time += T_time; sum_QT_time += QT_time; printf("%s\t%d\t%d\t %d\t %d\t %d\t %.2f\n", curpro->name, curpro->enter_time, curpro->copyRunning_time, curpro->start_time, curpro->done_time, T_time, QT_time); if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 pro[pronum].start_time = pro[pronum].enter_time; EnterQueue(queue, &pro[pronum]); pronum++; } continue; } for (int tt = time; tt <= time + timeslice && pronum < num; tt++) { //模拟进程的执行过程 if (tt >= pro[pronum].enter_time) { // 统计从此任务开始到结束之间有几个进程到达 pro[pronum].start_time = tt; EnterQueue(queue, &pro[pronum]); pronum++; } } time += timeslice; curpro->running_time -= timeslice; EnterQueue(queue, curpro); //当前程序未完成 继续添加到队列中 if (queue->size == 0 && pronum < num) { //防止出现前一个进程执行完到下一个进程到达之间无进程进入 pro[pronum].start_time = pro[pronum].enter_time; EnterQueue(queue, &pro[pronum]); pronum++; } } printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0)); } //选择菜单 void choiceMenu() { printf("请选择进程调度算法:\n"); printf("1.先来先服务算法\n"); printf("2.短进程优先算法\n"); printf("3.高优先级优先\n"); printf("4.时间片轮转算法\n"); }
test.cpp
#define _CRT_SECURE_NO_WARNINGS 1 #include"course.h" int main() { int proNum = 5; //5个进程 program pro[5]; inputProgram(pro, proNum); choiceMenu(); int choice; do { scanf("%d", &choice); switch (choice) { case 1: system("cls"); FCFS(pro, proNum); choiceMenu(); break; case 2: system("cls"); SJF(pro, proNum); choiceMenu(); break; case 3: system("cls"); HPF(pro, proNum); choiceMenu(); break; case 4: system("cls"); RR(pro, proNum); choiceMenu(); break; default: printf("输入错误,请重新尝试\n"); break; } } while (choice); return 0; }