一、 实验目的和要求
1. 了解进程调度算法的特点
2. 掌握进程调度算法,如先来先服务调度算法(first come first served,FCFS)、短作业优先调度算法(shotjob first,SJF)、时间片轮转调度算法。
二、 实验内容
设计模拟实现FCFS、SJF、时间片轮转调度算法的C语言程序
1. FCFS算法:按照作业/进程进入队列的先后顺序进行挑选,先进入的将先进行后续步骤的处理。
2. SJF算法:以进入系统的作业所要求的CPU运行时间的长短为挑选依据,优先选取预计所需服务时间最短的作业进行调度,可以分别用于高级调度和低级调度。
3. 时间片轮转算法:将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把处理机分配给队首进程,并令其执行一个时间片。
三、 实验步骤
1. 使用C++语言编译程序。
2. 完成算法代码。
3. 运行程序,算出结果。
四、 实验源程序
代码:
#include <stdio.h>
#include <iostream>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <cstring>
#include <cmath>
#define MAX 1111const double Max = 11111.0;using namespace std;typedef struct FCFS
{int mark;string name;double arrivetime;double servetime;double starttime;double finishtime;double roundtime;double daiquantime;bool operator< (const FCFS &a)const{return arrivetime > a.arrivetime;}}FCFS;typedef struct SJF
{int mark;string name;double arrivetime;double servetime;double starttime;double finishtime;double roundtime;double daiquantime;bool operator< (const SJF &a)const{return servetime > a.servetime;}}SJF;typedef struct RDRN{int mark;bool flag =true;string name;double Count =0.0;double arrivetime;double servetime;double starttime;double finishtime;double roundtime;double daiquantime;double running= 0.0;bool operator< (const RDRN &a)const{return Count > a.Count;}}RDRN;void FCFS_arithmetic()
{FCFS f[MAX];FCFS ff;int n;double averagedaiquantime = 0.0;priority_queue<FCFS> q1;printf("请输入作业数(整数)\n");scanf("%d",&n);printf("请输入n组数据,每组数据包括作业名字(字符串)、作业到达时间(浮点数)、作业服务时间(浮点数)(每组数据的给元素之间用空格隔开!):\n");for(int i=0;i<n; i++){f[i].mark =i;cin>>f[i].name;scanf("%lf%lf",&f[i].arrivetime,&f[i].servetime);q1.push(f[i]);}double starttime = 0.0;ff = q1.top();q1.pop();f[ff.mark].starttime = ff.arrivetime;f[ff.mark].finishtime = f[ff.mark].starttime + ff.servetime;f[ff.mark].roundtime = f[ff.mark].finishtime - f[ff.mark].arrivetime;f[ff.mark].daiquantime = f[ff.mark].roundtime / f[ff.mark].servetime;starttime =f[ff.mark].finishtime;printf("先来先服务调度算法的作用时间表:\n\n");printf("作业名字 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");cout<<" "<<f[ff.mark].name;printf("%10.2f %8.2f %8.2f %8.2f %8.2f%8.2f\n",f[ff.mark].arrivetime,f[ff.mark].servetime,f[ff.mark].starttime,f[ff.mark].finishtime,f[ff.mark].roundtime,f[ff.mark].daiquantime);while(!q1.empty()){ff =q1.top();q1.pop();f[ff.mark].starttime = starttime;f[ff.mark].finishtime = f[ff.mark].starttime + ff.servetime;f[ff.mark].roundtime = f[ff.mark].finishtime - f[ff.mark].arrivetime;f[ff.mark].daiquantime = f[ff.mark].roundtime / f[ff.mark].servetime;averagedaiquantime += f[ff.mark].daiquantime;starttime =f[ff.mark].finishtime;cout<<" "<<f[ff.mark].name;printf("%10.2f %8.2f %8.2f %8.2f %8.2f%8.2f\n",f[ff.mark].arrivetime,f[ff.mark].servetime,f[ff.mark].starttime,f[ff.mark].finishtime,f[ff.mark].roundtime,f[ff.mark].daiquantime);}printf("\n平均代权周转时间:\n");printf("%.2f\n",averagedaiquantime/n);}void SJF_arithmetic(){SJF f[MAX];SJF ff;int n;double starttime = Max;double averagedaiquantime = 0.0;priority_queue<SJF> q1;printf("请输入作业数(整数)\n");scanf("%d",&n);printf("请输入n组数据,每组数据包括作业名字(字符串)、作业到达时间(浮点数)、作业服务时间(浮点数)(每组数据的给元素之间用空格隔开!):\n");for(int i=0;i<n; i++){f[i].mark =i;cin>>f[i].name;scanf("%lf %lf",&f[i].arrivetime,&f[i].servetime);if(f[i].arrivetime < starttime) starttime = f[i].arrivetime;q1.push(f[i]);}printf("短作业优先调度算法的作用时间表:\n\n");int cnt = 0;while(!q1.empty()){SJF temp[MAX];ff =q1.top();q1.pop();if(f[ff.mark].arrivetime <= starttime){for(int i=0; i<cnt; i++) q1.push(temp[i]);cnt =0;f[ff.mark].starttime = starttime;f[ff.mark].finishtime = f[ff.mark].starttime + ff.servetime;f[ff.mark].roundtime = f[ff.mark].finishtime - f[ff.mark].arrivetime;f[ff.mark].daiquantime = f[ff.mark].roundtime / f[ff.mark].servetime;averagedaiquantime += f[ff.mark].daiquantime;starttime = f[ff.mark].finishtime;}else temp[cnt++] = ff;}printf("作业名字 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");for(int i=0;i<n; i++){cout<<" "<<f[i].name;printf("%10.2f %8.2f %8.2f %8.2f %8.2f%8.2f\n",f[i].arrivetime,f[i].servetime,f[i].starttime,f[i].finishtime,f[i].roundtime,f[i].daiquantime);}printf("\n平均代权周转时间:\n");printf("%.2f\n",averagedaiquantime/n);}void RDRN_arithmetic()
{double timeslice;RDRN f[MAX];RDRN temp[MAX];int cnt = 0;RDRN ff;int n;double averagedaiquantime = 0.0;priority_queue<RDRN> q1;printf("请输入作业数和时间片长度(作业数为整数,时间片长度可为浮点数,中间用空格隔开!):\n");scanf("%d%lf",&n,×lice);int tot = n;printf("请输入n组数据,每组数据包括作业名字(字符串)、作业到达时间(浮点数)、作业服务时间(浮点数)(每组数据的给元素之间用空格隔开!):\n");for(int i=0;i<n; i++){f[i].mark =i;cin>>f[i].name;scanf("%lf %lf",&f[i].arrivetime,&f[i].servetime);f[i].Count= f[i].arrivetime;q1.push(f[i]);}double clock =q1.top().arrivetime;int t = 0;while(t != n){ff =q1.top();if(f[ff.mark].arrivetime <= clock && tot-- > 0){q1.pop();if(f[ff.mark].flag){f[ff.mark].starttime = clock;f[ff.mark].flag = false;}if(f[ff.mark].running != f[ff.mark].servetime){double newtime = f[ff.mark].servetime - f[ff.mark].running;if(newtime >= timeslice){clock += timeslice;f[ff.mark].running += timeslice;f[ff.mark].Count += timeslice;}else{clock += newtime;f[ff.mark].running += newtime;f[ff.mark].Count += newtime;}if(f[ff.mark].running != f[ff.mark].servetime) temp[cnt++] = f[ff.mark];}if(f[ff.mark].running == f[ff.mark].servetime){t++;f[ff.mark].finishtime = clock;f[ff.mark].roundtime = f[ff.mark].finishtime - f[ff.mark].arrivetime;f[ff.mark].daiquantime = f[ff.mark].roundtime / f[ff.mark].servetime;averagedaiquantime += f[ff.mark].daiquantime;}}else{for(int i=0; i<cnt; i++) q1.push(temp[i]);cnt =0;tot =q1.size();}}printf("时间轮转调度算法的作用时间表:\n\n");printf("作业名字 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");for(int i=0;i<n; i++){cout<<" "<<f[i].name;printf("%10.2f %8.2f %8.2f %8.2f %8.2f %8.2f\n",f[i].arrivetime,f[i].servetime,f[i].starttime,f[i].finishtime,f[i].roundtime,f[i].daiquantime);}printf("\n平均代权周转时间:\n");printf("%.2f\n",averagedaiquantime/n);}int main(){printf("********************************************************欢迎您!***********************************************************\n");int ca = 0;do{printf("\n请选择调度算法或结束程序:\n");printf("0、结束程序\n1、先来先服务\n2、短作业优先\n3、时间片轮转\n");scanf("%d",&ca);if(ca == 1)FCFS_arithmetic();if(ca == 2)SJF_arithmetic();if(ca == 3) RDRN_arithmetic();}while(ca);return 0;}
五、 实验结果
先来先服务调度算法:
短作业优先调度算法:
时间片轮转调度算法: