进程调度算法
一、 实验目的
用C语言模拟进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容和要求
设计一个有 N个进程并发执行的进程调度模拟程序。
1.模拟进程数据的生成
用户选择输入每个进程的到达时间,所需运行时间,进程的运行时间以时间片为单位。
2. 模拟调度程序的功能
按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法:
FCFS
SJF
RR
优先级调度算法
显示每种算法下各进程的调度执行顺序。
计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间。
模拟数据结果分析:对同一组模拟数据,比较各算法的平均周转时间,周转系数。
实验方法、步骤及结果测试
具体算法:
#include<stdio.h> #include<stdlib.h> #define MAX 100 /*定义进程结构体*/ typedef struct pcb { char name[30];//进程名称 int priority ;//进程优先数 float arriveTime;//进程到达时间 float serveTime;//进程服务时间 float finishTime;//进程完成时间 int cpuTime;//进程占用CPU时间 float roundTime;//带权 char state;//进程状态 } PCB; PCB p[MAX]; Output(PCB p[MAX],int n); PrioritySort(PCB p[MAX],int n); Run_hrrf(PCB p[MAX] , int n); Input_sjf(PCB p[MAX],int count); Input_hrrf(PCB p[MAX],int n); Input_fcfs(PCB p[MAX],int count); Input_rr(PCB p[MAX],int count,int num); void fcfs(); void HRRF(); void FCFS(); void SJF(); void RR(); void Menu() { printf("\n\t-----------------欢迎进入进程调度模拟程序-----------------\n"); printf("\t ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n"); printf("\t ┃可选择算法操作: ┃\n"); printf("\t ┣━━━━━━━━━━━━┳━━━━━━━━━━━━┫\n"); printf("\t ┃1.响应比高者优先调度算法┃2.时间片轮转调度算法 ┃\n"); printf("\t ┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n"); printf("\t ┃3.短作业优先调度算法 ┃4.先来先服务调度算法 ┃\n"); printf("\t ┣━━━━━━━━━━━━┻━━━━━━━━━━━━┫\n"); printf("\t ┃ 0.退出系统 ┃\n"); printf("\t ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n"); } main() { char choice; //算法编号选择 Menu: Menu();//显示菜单 printf("请选择对应序号:"); scanf("%d",&choice); //输入算法编号 system("cls"); switch(choice) { case 1: printf("\n *************进程调度算法(响应比高者优先调度算法)************\n\n"); HRRF(); break; case 2: printf("\n *************进程调度算法(时间片轮转调度算法)************\n\n"); RR(); break; case 3: printf("\n *************进程调度算法(短作业优先调度算法)************\n\n"); SJF(); break; case 4: printf("\n *************进程调度算法(先来先服务调度算法)************\n\n"); printf("请输入进程数目:"); FCFS(); break; case 0: break; default: printf("\n输入有误请重新输入。\n"); break; } printf(".............回到主菜单......!\n"); goto Menu ; } Output(PCB p[MAX],int n) { int i; printf("进程名称\t优先级数\t服务时间\t当前时间\t进程状态\n"); for(i=0; i<n; i++) { printf(" %s\t",p[i].name); printf("\t%d\t",p[i].priority); printf("\t%f\t",p[i].serveTime); printf("\t%d\t",p[i].cpuTime); printf("\t%c\t",p[i].state); printf("\n"); } } PrioritySort(PCB p[MAX],int n) { int m=0,i=0,j ; PCB temp; m = n; for(i = 1 ; i < n ; i++) { m = m - 1 ; for(j = 0 ; j < m ; j ++) { if(p[j].priority < p[j+1].priority) { temp = p[j]; p[j] = p[j+1]; p[j+1] = temp ; } } } } Run_hrrf(PCB p[MAX] , int n) { int i ,j ; float m=0; for(i = 0 ; i < n ; i ++) { m = p[i].serveTime+m; } for(i = 0 ; i <= n ; i ++) { for(j = 0 ; j <= m ; j ++) { printf("请按回车键继续运行......!\n"); PrioritySort(p,n); getchar(); p[i].priority--; p[i].cpuTime++; p[i].serveTime--; p[i].state='R'; Output(p,n); if(p[i].serveTime!=0) { p[i].state='R'; } else { p[i].state='F'; break; } } } } Input_hrrf(PCB p[MAX],int n) { int i; for(i=0; i<n; i++) { printf("第%d个进程的名称:",i+1); scanf("%s",&p[i].name); printf("第%d个进程的优先数:",i+1); scanf("%d",&p[i].priority); printf("第%d个进程的服务时间:",i+1); scanf("%f",&p[i].serveTime); p[i].state='W'; p[i].cpuTime=0; printf("\n"); } } void HRRF(){ int number; printf("请输入进程数目:"); scanf("%d",&number); //输入进程数目 Input_hrrf(p,number); PrioritySort(p,number); Output(p,number); getchar(); Run_hrrf(p,number); } Input_fcfs(PCB p[MAX],int count) { int i ; printf("使用FCFS算法:\n"); for(i=0;i<count;i++){ printf("输入第 %d 个进程的名字:\n",i+1); scanf("%s",&p[i].name); printf("输入第 %d 个进程所需的进程时间:\n",i+1); scanf("%f",&p[i].serveTime); } } void fcfs(PCB p[MAX],int count){ int i ; float t; float w; float s=0; float s1=0; float sum=0; printf("\n"); printf("所输入的进程如下:\n"); printf("name\t serveTime\t\n"); for(i=0;i<count;i++){ printf("%s\t %f\t\n",p[i].name,p[i].serveTime); } printf("\n"); printf("算法结果如下:\n"); printf("number\t name\t serveTime\t\n"); for(i=0;i<count;i++){ printf("%s\t %f\t\n",p[i].name,p[i].serveTime); s=s+p[i].serveTime; p[i].roundTime=s/p[i].serveTime; s1=s1+p[i].roundTime; sum=sum+s; } t=sum/count; w=s1/count; printf("平均作业周转时间为:%f\n",t); printf("平均带权周转时间为:%f\n",w); } void FCFS(){ PCB p[MAX]; int count; scanf("%d",&count); Input_fcfs(p,count); fcfs(p,count); } Input_sjf(PCB p[MAX],int count) { int i ; printf("使用SJF算法:\n"); for(i=0;i<count;i++){ printf("输入第 %d 个进程的名字:\n",i+1); scanf("%s",&p[i].name); printf("输入第 %d 个进程所需的进程时间:\n",i+1); scanf("%f",&p[i].serveTime); printf("\n"); } } void sjf(PCB p[MAX],int count){ int i; int j; float t; float w; float s=0; float s1=0; float sum=0; PCB temp; printf("\n"); printf("所输入的进程如下:\n"); printf("name\t usetime\t\n"); for(i=0;i<count;i++){ printf("%s\t %f\t\n",p[i].name,p[i].serveTime); } for(i=0;i<count-1;i++){ for(j=i+1;j<count;j++){ if(p[j].serveTime<p[i].serveTime) { temp=p[j]; p[j]=p[i]; p[i]=temp; } } } printf("\n"); printf("算法结果如下:\n"); printf("number\t name\t serveTime\t\n"); for(i=0;i<count;i++){ printf("%d\t %s\t %f\t\n",i+1,p[i].name,p[i].serveTime); } for(i=0;i<count;i++){ s=s+p[i].serveTime; p[i].roundTime=s/p[i].serveTime; s1=s1+p[i].roundTime; sum=sum+s; } t=sum/count; w=s1/count; printf("平均作业周转时间为:%f\n",t); printf("平均带权周转时间为:%f\n",w); } void SJF(){ PCB p[MAX]; int count; printf("请输入进程数:\n"); scanf("%d",&count); Input_sjf(p,count); sjf(p,count); } Input_rr(PCB p[MAX],int count,int num){ int i , j ; for(i=0; i<count; i++) { printf("第%d个进程的名称:",i+1); scanf("%s",&p[i].name); printf("第%d个进程的服务时间:",i+1); scanf("%f",&p[i].serveTime); printf("\n"); } x: for(j = 0 ; j < count ; j ++){ for(i= 0 ; i < num ; i ++){ if(p[j].serveTime == 0){ break; }else{ p[j].serveTime--; } } printf("number serveTime\n "); printf("%s\t %f\t \n",p[j].name,p[j].serveTime); } printf("\n───────────────────────\n"); if(p[count-1].serveTime!=0){ goto x ; } } void RR(){ PCB p[MAX]; int count; int num; printf("请输入进程数:\n"); scanf("%d",&count); printf("请输入时间片时间:"); scanf("%d",&num); Input_rr(p,count,num); }
程序主界面:
优先级调度算法:
时间片轮转(RR)算法:
最短作业优先算法(SJF):
先来先服务算法(FCFS):
三、实验总结
理论简单,用语言模拟起来比较困难,会出现种种的问题,大部分都得到了解决。本程序还存在各种各样的BUG,参考者需谨慎使用。。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?