一、 实验目的
(1)加深对作业调度算法的理解;
(2)进行程序设计的训练。
二、 实验内容和要求
用高级语言编写一个或多个作业调度的模拟程序。
单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。
三、 实验方法、步骤及结果测试
作业调度算法:
采用先来先服务(FCFS)调度算法、短作业(SJF)算法以及最高响应比(HRRF)算法。
拓展内容:
- 每个作业的到达时间和所需运行时间随机数生产;
- 文件读取作业;
- 显示作业调度的结果,显示各个队列;
- 允许用户在模拟过程中提交新作业。
#include<stdio.h> #include<string.h> #include<time.h> typedef struct jcb{ char name[10];//作业名 int arrtime;//到达时间 int reqtime;//要求服务时间 int startime;//调度时间 int finitime;//结束时间 float TAtime,TAWtime;//周转时间,带权周转时间(周转时间/服务时间) float prio; }JCB; int systime=0; int intarr=0,intfin=0,intjob=0;//到达作业个数,完成作业个数,未到达作业个数 JCB jobarr[24],jobfin[24],job[24]; void Mune() { printf("\n\n"); printf("\t\t|------------------------------------------------|\n"); printf("\t\t| 作业调度模拟程序 |\n"); printf("\t\t|------------------------------------------------|\n"); printf("\t\t| 0:退出 |\n"); printf("\t\t| 1:从文件读取输入 |\n"); printf("\t\t| 2:伪随机数产生 |\n"); printf("\t\t| 3:自己输入模拟数据 |\n"); printf("\t\t|------------------------------------------------|\n"); printf("请选择<0~3>:"); } void Mune2() { printf("\n\n"); printf("\t\t|------------------------------------------------|\n"); printf("\t\t| 作业调度模拟程序 |\n"); printf("\t\t|------------------------------------------------|\n"); printf("\t\t| 0:退出 |\n"); printf("\t\t| 1:先到先服务算法 |\n"); printf("\t\t| 2:短作业优先算法 |\n"); printf("\t\t| 3:最高响应比优先算法 |\n"); printf("\t\t| 4:插入 |\n"); printf("\t\t| 5:删除(仅删除在未到达队列中的作业) |\n"); printf("\t\t|------------------------------------------------|\n"); printf("请选择<0~3>:"); } //从文件读取 int ReadFile() { int i=0; FILE *fp; //定义文件指针 fp=fopen("3.txt","r"); //打开文件 if(fp==NULL) { printf("File open error !\n"); exit(0); } while(!feof(fp)) { fscanf(fp,"%s%d%d",&job[i].name,&job[i].arrtime,&job[i].reqtime); //fscanf()函数将数据读入 i++; }; if(fclose(fp)) //关闭文件 { printf("Can not close the file !\n"); exit(0); } return i; } //伪随机数产生 void Pseudo_random_number() { int i; char str[25]; srand((unsigned)time(0)); //参数seed是rand()的种子,用来初始化rand()的起始值。 //输入作业数 intjob=rand()%23+5; for(i=1;i<=intjob;i++) { itoa(i, str, 10);//数字转换成字符 strcpy(job[i-1].name,str); //作业到达时间 job[i-1].arrtime=rand()%29+1; //作业运行时间 job[i-1].reqtime=rand()%7+1; } } void Input()//手动输入 { int i; int j; int n=0; printf("请输入作业个数:"); scanf("%d",&n); for(i=0;i<n;i++,intjob++) { printf("\n第%d个作业:\n请输入作业名:",i+1); scanf("%s",job[intjob].name); do{ printf("请输入到达时间:"); scanf("%d",&job[intjob].arrtime); if(job[i].arrtime<systime) printf("到达时间小于当前系统时间!请重新输入:"); }while(job[i].arrtime<systime); printf("请输入要求服务时间:"); scanf("%d",&job[intjob].reqtime); job[i].startime=0; job[i].finitime=0; job[i].TAtime=0; job[i].TAWtime=0; } for(i=0;i<intjob;i++)//若输入到达时间为现在的系统时间 { if(job[i].arrtime==systime) { jobarr[intarr]=job[i]; for(j=i;j<=intjob;j++) { job[j]=job[j+1]; } intarr++; intjob--; i--; } else if(job[i].arrtime<systime) { printf("到达时间小于当前系统时间!请重新输入"); } } } void Output()//输出排序后队列 { int i; printf("\n\n\n未到达队列的是\n"); printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n"); for(i=0;i<intjob;i++){ printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,job[i].name,job[i].arrtime,job[i].reqtime,job[i].startime,job[i].finitime,job[i].TAtime,job[i].TAWtime); } printf("\n已到达队列的是\n"); printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n"); for(i=0;i<intarr;i++){ printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,jobarr[i].name,jobarr[i].arrtime,jobarr[i].reqtime,jobarr[i].startime,jobarr[i].finitime,jobarr[i].TAtime,jobarr[i].TAWtime); } printf("\n已完成队列的是\n"); printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n"); for(i=0;i<intfin;i++){ printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,jobfin[i].name,jobfin[i].arrtime,jobfin[i].reqtime,jobfin[i].startime,jobfin[i].finitime,jobfin[i].TAtime,jobfin[i].TAWtime); } printf("现在系统时间:%d",systime); printf("\n*********************************************\n"); } void Sort1(JCB job[])//按到达时间排序 { int i,j; JCB temp; for(i=0;i<intjob-1;i++) { for(j=i+1;j<intjob;j++) { if(job[i].arrtime>job[j].arrtime) { temp=job[i]; job[i]=job[j]; job[j]=temp; } } } } //按运行时间长度排序 void Sort2(JCB job[]) { int i,j; JCB temp; for(i=1;i<intjob-1;i++) { for(j=i+1;j<intjob;j++) { if(job[i].reqtime>job[j].reqtime) { temp=job[i]; job[i]=job[j]; job[j]=temp; } } } } //按响应比排序 void Sort3(JCB job[]) { int i,j; JCB temp; for(i=1;i<intjob-1;i++) { for(j=i+1;j<intjob;j++) { if(job[i].prio>job[j].prio) { temp=job[i]; job[i]=job[j]; job[j]=temp; } } } } //先来先服务算法 void Fcfs(){ int i,j=0,k; while(job[0].arrtime>systime) { systime++; } if(intjob!=0) { jobarr[intarr]=job[0]; for(k=0;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; } while(0<intarr) { i=0; printf("\n作业%s开始运行...\n",jobarr[i].name); jobarr[i].startime=systime; jobarr[i].finitime=systime+jobarr[i].reqtime; while(jobarr[i].finitime>systime||intjob>0) { systime++; while(job[j].arrtime==systime)//作业从未到达队列进入已到达队列 { jobarr[intarr]=job[0]; for(k=j;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; } } jobarr[i].TAtime=jobarr[i].finitime-jobarr[i].arrtime; jobarr[i].TAWtime=jobarr[i].TAtime/jobarr[i].reqtime; jobfin[intfin]=jobarr[i]; printf("作业%s运行结束!\n",jobarr[i].name); printf("\n现在系统时间:%d\n",systime); printf("\n*********************************************\n"); for(k=i;k<=intarr;k++)//队列中剩余元素前移 { jobarr[k]=jobarr[k+1]; } intarr--; intfin++; } } //短作业优先 void SJF() { int i,j=0,k; while(job[0].arrtime>systime) { systime++; } if(intjob!=0) { jobarr[intarr]=job[0]; for(k=0;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; } while(0<intarr) { i=0; printf("\n作业%s开始运行...\n",jobarr[i].name); jobarr[i].startime=systime; jobarr[i].finitime=systime+jobarr[i].reqtime; while(jobarr[i].finitime>systime||intjob>0) { systime++; while(job[j].arrtime==systime)//作业从未到达队列进入已到达队列 { jobarr[intarr]=job[0]; for(k=j;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; Sort2(jobarr); } } jobarr[i].TAtime=jobarr[i].finitime-jobarr[i].arrtime; jobarr[i].TAWtime=jobarr[i].TAtime/jobarr[i].reqtime; jobfin[intfin]=jobarr[i]; printf("作业%s运行结束!\n",jobarr[i].name); printf("\n现在系统时间:%d\n",systime); printf("\n*********************************************\n"); for(k=i;k<=intarr;k++)//队列中剩余元素前移 { jobarr[k]=jobarr[k+1]; } intarr--; intfin++; } } //响应比 void Hrrf() { int i,j=0,k; while(job[0].arrtime>systime) { systime++; } if(intjob!=0) { jobarr[intarr]=job[0]; for(k=0;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; } while(0<intarr) { i=0; printf("\n作业%s开始运行...\n",jobarr[i].name); jobarr[i].startime=systime; jobarr[i].finitime=systime+jobarr[i].reqtime; while(jobarr[i].finitime>systime||intjob>0) { systime++; while(job[j].arrtime==systime)//作业从未到达队列进入已到达队列 { jobarr[intarr]=job[0]; for(k=j;k<=intjob;k++) { job[k]=job[k+1]; } intarr++; intjob--; Sort3(jobarr); } } jobarr[i].TAtime=jobarr[i].finitime-jobarr[i].arrtime; jobarr[i].TAWtime=jobarr[i].TAtime/jobarr[i].reqtime; jobfin[intfin]=jobarr[i]; printf("作业%s运行结束!\n",jobarr[i].name); printf("\n现在系统时间:%d\n",systime); printf("\n*********************************************\n"); for(k=i;k<=intarr;k++)//队列中剩余元素前移 { jobarr[k]=jobarr[k+1]; } intarr--; intfin++; //计算响应比 if(systime-jobarr[i].startime>0&&intarr!=0) jobarr[i].prio=1+(systime-jobarr[i].startime)/jobarr[i].reqtime; } } void Delete() { char b[20]; int i,j,key=0; printf("请输入要删除的作业名:"); scanf("%s",b); for(i=0;i<intjob;i++) { if(strcmp(b,job[i].name)==0) { key=1; for(j=i;j<=intjob;j++) { job[j]=job[j+1]; } intjob--; } } if(key==0) { printf("查找不到该作业!"); } } main() { int chose,i,j; Mune(); scanf("%d",&chose); switch(chose)//选择输入 { case 0:exit(0); case 1:intjob=ReadFile();break; case 2:Pseudo_random_number();break; case 3:Input();break; default:printf("输入错误!"); } for(i=0;i<intjob;i++)//若输入到达时间为现在的系统时间 { if(job[i].arrtime==systime) { jobarr[intarr]=job[i]; for(j=i;j<=intjob;j++) { job[j]=job[j+1]; } intarr++; intjob--; i--; } } //排序 Sort1(job); Sort1(jobarr); Output(); systime++; while(1) { Mune2(); scanf("%d",&chose); switch(chose) { case 0:exit(0);break; case 1:Fcfs();break; case 2:SJF();break; case 3:Hrrf();break; case 4:Input();break; case 5:Delete();break; default:printf("输入错误!"); } Sort1(job); Sort1(jobarr); Output(); systime++; } }
运行结果: