操作系统进程调度算法的模拟实现(c语言版本)
前言:本文旨在分享如何使用c语言对操作系统中的部分进程调度算法进行模拟实现,以及算法描述的讲解,完整代码放在文章末尾,欢迎大家自行拷贝调用

目录
常见的调度算法
数据结构
先来先服务调度算法
算法模拟思路:
算法模拟:
最短作业优先调度算法
算法模拟思路:
算法模拟:
最高优先级调度算法
算法模拟思路:
算法模拟:
时间片轮转调度算法
算法模拟思路:
算法模拟:
完整代码:
course.h:
course.cpp:
test.cpp:
常见的调度算法
- 先来先服务调度算法
- 最短作业优先调度算法
- 高响应比优先调度算法
- 最高优先级调度算法
- 时间片轮转调度算法
- 多级反馈队列调度算法
- ... ...
数据结构
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;
}
本次的分享就到此为止了,感谢您的支持,如果您有不同意见,欢迎评论区积极交流
相关文章:
操作系统进程调度算法的模拟实现(c语言版本)
前言:本文旨在分享如何使用c语言对操作系统中的部分进程调度算法进行模拟实现,以及算法描述的讲解,完整代码放在文章末尾,欢迎大家自行拷贝调用 目录 常见的调度算法 数据结构 先来先服务调度算法 算法模拟思路: …...
webbench压测工具
介绍 webbench是Linux下的一个网站压力测试工具,最多可以模拟3万个并发连接去测试网站的负载能力。 https://soft.lnmp.com/test/webbench/ 安装非常简单 tar zxvf webbench-1.5.tar.gz cd webbench-1.5 make && make install会在当前目录生成webbench可执…...
HarmonyOS 音频开发指导:使用 OpenSL ES 开发音频播放功能
OpenSL ES 全称为 Open Sound Library for Embedded Systems,是一个嵌入式、跨平台、免费的音频处理库。为嵌入式移动多媒体设备上的应用开发者提供标准化、高性能、低延迟的 API。HarmonyOS 的 Native API 基于Khronos Group开发的OpenSL ES 1.0.1 API 规范实现&am…...
docker搭建个人镜像仓库
docker搭建个人镜像仓库 安装registry mkdir docker-registry cd docker-registry mkdir registry mkdr auth vim docker-compose.ymldocker-compose.yml的内容如下: version: 3 services:registry:image: registrycontainer_name: registryvolumes:- ./registry…...
Python机器学习17——Xgboost和Lightgbm结合分位数回归(机器学习与传统统计学结合)
最近XGboost支持分位数回归了,我看了一下,就做了个小的代码案例。毕竟学术市场上做这种新颖的机器学习和传统统计学结合的方法还是不多,算的上创新,找个好数据集可以发论文。 代码实现 导入包 import numpy as np import pandas…...
C#编程学习
1. **C#简介**: - C#是一种现代的、面向对象的编程语言,由Microsoft开发。 - 它是.NET框架的一部分,用于开发Windows应用程序、Web应用程序和服务等。 2. **开发环境**: - 你可以使用Visual Studio或Visual Studio Code…...
关于vue 父级不使用子级某模块 (插槽替换)
父级: <template><div><MoreSupplements code"Xmgk" message"补充内容越多,越精准"><template #r-btn>xxx</template></MoreSupplements></div> </template> <script> import MoreSupplements fr…...
睿趣科技:抖音小店在哪里选品
随着抖音平台的日益火爆,越来越多的商家选择在抖音小店开设自己的店铺。然而,对于许多新手来说,如何选品却成为了一个难题。那么,抖音小店应该在哪里选品呢? 首先,我们可以从抖音平台上的热门商品入手。通过观察抖音上…...
量变引起质变:安卓改多了,就是自己的OS
最近小米也发布了自己的OS,其他也有厂家跟进。这是自华为鸿蒙之后,大家都说自己开发OS。对此,也是有很多争论的。 有人说,这些东西不都是安卓套壳或者改名吗?怎么就变成了自己的OS?这种观点对不对呢&#x…...
IDEA 之 在不更改操作系统用户名的情况下更改 ${USER} 变量?
如何在不更改操作系统用户名的情况下更改 IntelliJ IDEA 中的 ${USER} 变量 IDEA -> Help -> Edit Custom VM 添加如下内容 -Duser.nameusername这样在文件或者函数注释的时候会读取这个配置,而不会读取电脑登录用户名...
基于JAVA的天猫商场系统设计与实现,springboot+jsp,MySQL数据库,前台用户+后台管理,完美运行,有一万五千字论文
目录 演示视频 基本介绍 论文目录 系统截图 演示视频 基本介绍 基于JAVA的天猫商场系统设计与实现,springbootjsp,MySQL数据库,前台用户后台管理,完美运行,有一万五千字论文。 本系统在HTML和CSS的基础上…...
Redis学习
缓存定义 缓存是一个告诉数据交换的存储器,使用它可以快速的访问和操作数据。 常见缓存使用 本地缓存的常见使用:Spring Cache、MyBatis的缓存等 我的session存储和redis都放到缓存里面的,所有程序不管部署多少份,访问的都是r…...
uni-app:实现picker下拉列表的默认值设置
效果 分析 1、在data中将index8的初始值设置为-1,表示未选择任何选项: index8: -1, //选择的下拉列表下标 2、在bindPickerChange8事件处理函数中添加条件判断。如果选择的值是-1,则将this.index8设置为"请输入",否则将…...
基于NB-iot技术实现财物跟踪的EA01-SG定位模块方案
NB-iot无线数传模块可做财物防盗窃器,让你的财物可定位跟踪! 随着社会的发展,公共资源及共享资源的蓬勃发展,对资产管理和资产追踪有了新的需求,如:某儿童玩具车在商场外面提供车辆乘坐游玩服务࿰…...
挑战吧,HarmonyOS应用开发工程师
一年一度属于工程师的专属节日1024,多重活动亮相啦~ 参与活动即有机会获得HUAWEI Freebuds 5i 耳机等精美礼品! 点击“阅读原文”查看更多活动详情!...
图论05-【无权无向】-图的广度优先BFS遍历-路径问题/检测环/二分图/最短路径问题
文章目录 1. 代码仓库2. 单源路径2.1 思路2.2 主要代码 3. 所有点对路径3.1 思路3.2 主要代码 4. 联通分量5. 环检测5.1 思路5.2 主要代码 6. 二分图检测6.1 思路6.2 主要代码6.2.1 遍历每个联通分量6.2.2 判断相邻两点的颜色是否一致 7. 最短路径问题7.1 思路7.2 代码 1. 代码…...
uniapp:谷歌地图,实现地图展示,搜索功能,H5导航
页面展示 APP H5 谷歌地图功能记录,谷歌key申请相对复杂一些,主要需要一些国外的身份信息。 1、申请谷歌key 以下是申请谷歌地图 API 密钥的流程教程: 登录谷歌开发者控制台:打开浏览器,访问 Google Cloud Platform Console。 1、创建或选择项目:如果你还没有创建项目…...
关于腾讯云轻量应用服务器性能测评,看这一篇文章就够了
腾讯云轻量应用服务器性能如何?为什么便宜是不是性能不行?腾讯云百科txybk.com从轻量应用服务器的CPU型号、处理器主频、内存、公网带宽、月流量和系统盘多方面来详细测评轻量性能,轻量应用服务器性价比高,并不是性能不行…...
HDFS集群NameNode高可用改造
文章目录 背景高可用改造方案实施环境准备配置文件修改应用配置集群状态验证高可用验证 背景 假定目前有3台zookeeper服务器,分别为zk-01/02/03,DataNode服务器若干; 目前HDFS集群的Namenode没有高可用配置,Namenode和Secondary…...
Spark集群中一个Worker启动失败的排错记录
文章目录 1 检查失败节点worker启动日志2 检查正常节点worker启动日志3 查看正常节点spark环境配置4 又出现新的ERROR4.1 报错解释4.2 报错解决思路4.3 端口报错解决操作 集群下电停机后再次启动时,发现其中一台节点的worker启动失败。 1 检查失败节点worker启动日…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
