---恢复内容开始---
一、目的和要求
1. 实验目的
(1)加深对作业调度算法的理解;
(2)进行程序设计的训练。
2.实验要求
用高级语言编写一个或多个作业调度的模拟程序。
单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。
作业调度算法:
1) 采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间
每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。
一、 模拟数据的生成
1. 允许用户指定作业的个数(2-24),默认值为5。
2. 允许用户选择输入每个作业的到达时间和所需运行时间。
3. (**)从文件中读入以上数据。
4. (**)也允许用户选择通过伪随机数指定每个作业的到达时间(0-30)和所需运行时间(1-8)。
二、 模拟程序的功能
1. 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
2. 动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。
3. (**)允许用户在模拟过程中提交新作业。
4. (**)编写并调度一个多道程序系统的作业调度模拟程序。 只要求作业调度算法:采用基于先来先服务的调度算法。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。
三、 模拟数据结果分析
1. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
2. (**)用曲线图或柱形图表示出以上数据,分析算法的优点和缺点。
四、 其他要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、源代码
#include"stdio.h"
#define N 50
void main()
{ void sjp();
void fcfs();
void sjf();
void yxj();
int a;
while(true)
{
printf(" ");
printf(" /*************************/");
printf(" /* 1、先到先服务 调 度 */");
printf(" /* 2、短作业优先 调 度 */");
printf(" /* 3、时间片轮转 调 度 */");
printf(" /* 4、优先级优先 调 度 */");
printf(" /* 0、 退 出 */ ");
printf(" /*************************/");
printf(" 请选择菜单项: ");
scanf("%d",&a);
printf(" ");
switch(a)
{
case 1: fcfs();break;
case 2: sjf();break;
case 3: sjp();break;
case 4: yxj();break;
default: break;
}
if(a<0&&a>4) break;
}
}
void sjp()
{
int i,j,n,min,px,sjp,time;
float sum1,sum2;
bool flag=true;
printf(" 请输入有n个进程(0<n<=50): ");
scanf("%d",&n);
while(n>50||n<=0)
{
printf("n 请重新输入: ");
scanf("%d",&n);
}
printf(" ");
printf(" 请输入时间片大小(0<sjp): ");
scanf("%d",&sjp);
while(sjp<=0)
{
printf("n 请重新输入: ");
scanf("%d",&sjp);
}
struct Gzuo{
int id; //进程名字
int dt; //到达时刻
int st; //服务时间
int wct; //完成时刻
int st2; //标志是否完成
float zt; //周转时间
float dczt; //带权周转时间
};
Gzuo a[N];
for(i=0;i<n;i++)
{
a[i].id=i+1;
printf(" 到达时间: ");
scanf("%d",&a[i].dt);
printf(" 服务时间: ");
scanf("%d",&a[i].st);
a[i].st2 = a[i].st;
printf(" ");
}
for(j=n-1;j>=0;j--)
{
for(i=0;i<j;i++)
{
if(a[i].dt>a[i+1].dt)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].st2;
a[i].st2=a[i+1].st2;
a[i+1].st2=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
time = a[0].dt;
//printf("赋值后TIME值为:%d ",time);
min = 0;
while(min<n)
{
flag = true;
for(i = 0;i<n;i++)
{
if(a[i].st2>0&&a[i].dt<=time)
flag = false;
}
for(i=0;i<n;i++)
{
if(a[i].st2 > 0 )
{
if(a[i].dt<=time)
{
//printf("当前a[%d].st2值为:%d ",i,a[i].st2);
a[i].st2 = a[i].st2 - sjp;
//printf("运算后当前a[%d].st2值为:%d ",i,a[i].st2);
//printf("当前TIME值为:%d ",time);
time = time + sjp;
//printf("增加之后TIME值为:%d ",time);
if(a[i].st2<=0)
{
a[i].wct = time + a[i].st2;
a[i].zt=(float)(a[i].wct-a[i].dt);
a[i].dczt=a[i].zt/a[i].st;
min++;
}
}else if(flag)
{
for(i=0;i<n;i++)
{
if(a[i].st2>0&&a[i].dt>time)
{
time = a[i].dt;
break;
}
}
}
}
}
}
printf(" 1、按id号依次输出 ");
printf(" 2、按完成顺序依次输出 ");
printf(" 请选择输出顺序: ");
scanf("%d",&px);
printf(" id:到达时间 服务时间 完成时间 周转时间 带权周转时间 ");
sum1=0;
sum2=0;
switch(px)
{
case 2:
{
for(i=0;i<n;i++)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
case 1:
{
for(j=0;j<n;j++)
{
for(i=0;i<n;i++)
if(a[i].id==j+1)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
default: break;
}
}
void fcfs()
{
int i,j,n,min,px;
float sum1,sum2;
printf(" 请输入有n个进程(0<n<=50): ");
scanf("%d",&n);
while(n>50||n<=0)
{
printf("n 请重新输入: ");
scanf("%d",&n);
}
printf(" ");
struct Gzuo{
int id; //进程名字
int dt; //到达时刻
int st; //服务时间
int wct; //完成时刻
float zt; //周转时间
float dczt; //带权周转时间
};
Gzuo a[N];
for(i=0;i<n;i++)
{
a[i].id=i+1;
printf(" 到达时间: ");
scanf("%d",&a[i].dt);
printf(" 服务时间: ");
scanf("%d",&a[i].st);
printf(" ");
}
for(j=n-1;j>=0;j--)
{
for(i=0;i<j;i++)
{
if(a[i].dt>a[i+1].dt)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
a[0].wct=a[0].st+a[0].dt;
a[0].zt=(float)a[0].st;
a[0].dczt=a[0].zt/a[0].st;
for(i=1;i<n;i++)
{
if(a[i].dt>a[i-1].wct)
{
a[i].wct=a[i].dt+a[i].st;
a[i].zt=(float)a[i].st;
a[i].dczt=a[i].zt/a[i].st;
}
else
{
a[i].wct=a[i-1].wct+a[i].st;
a[i].zt=(float)(a[i].wct-a[i].dt);
a[i].dczt=a[i].zt/a[i].st;
}
}
printf(" 1、按id号依次输出 ");
printf(" 2、按完成顺序依次输出 ");
printf(" 请选择输出顺序: ");
scanf("%d",&px);
printf(" id:到达时间 服务时间 完成时间 周转时间 带权周转时间 ");
sum1=0;
sum2=0;
switch(px)
{
case 2:
{
for(i=0;i<n;i++)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
case 1:
{
for(j=0;j<n;j++)
{
for(i=0;i<n;i++)
if(a[i].id==j+1)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
default: break;
}
}
void sjf()
{
int i,j,n,min,px;
int b=0,z;
float sum1,sum2;
printf(" 请输入有n个进程(0<n<=50): ");
scanf("%d/n",&n);
while(n>50||n<=0)
{
printf("n 请重新输入: ");
scanf("%d",&n);
}
printf(" ");
struct Gzuo{
int id; //进程名字
int dt; //到达时刻
int st; //服务时间
int wct; //完成时刻
float zt; //周转时间
float dczt; //带权周转时间
};
Gzuo a[N];
for(i=0;i<n;i++)
{
a[i].id=i+1;
printf(" 到达时间: ");
scanf("%d",&a[i].dt);
printf(" 服务时间: ");
scanf("%d",&a[i].st);
printf(" ");
}
min=a[0].dt;
for(j=n-1;j>=0;j--)
{
for(i=0;i<j;i++)
{
if(a[i].dt>a[i+1].dt)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
if(a[i].dt==a[i+1].dt&&a[i].st>a[i+1].st)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
a[0].wct=a[0].st+a[0].dt;
a[0].zt=(float)a[0].st;
a[0].dczt=a[0].zt/a[0].st;
for(i=1;i<n;i++)
{
if(a[i].dt>a[0].wct) ;
else b=b+1;
}
for(j=b-1;j>=1;j--)
{
for(i=1;i<j;i++)
{
if(a[i].st>a[i+1].st)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
for(i=1;i<n;i++)
{
if(a[i].dt>a[i-1].wct)
{
a[i].wct=a[i].dt+a[i].st;
a[i].zt=(float)a[i].st;
a[i].dczt=a[i].zt/a[i].st;
}
else
{
a[i].wct=a[i-1].wct+a[i].st;
a[i].zt=(float)(a[i].wct-a[i].dt);
a[i].dczt=a[i].zt/a[i].st;
}
for(j=i+1,b=j;j<n;j++)
{
if(a[j].dt>a[i].wct) ;
else b=b+1;
}
for(j=b-1;j>=i;j--)
{
for(z=i;z<j;z++)
{
if(a[z].st>a[z+1].st)
{
min=a[z].dt;
a[z].dt=a[z+1].dt;
a[z+1].dt=min;
min=a[z].st;
a[z].st=a[z+1].st;
a[z+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
}
printf(" 请选择输出顺序 ");
printf(" 1、按id号依次输出 ");
printf(" 2、按完成顺序依次输出 ");
scanf("%d",&px);
printf(" id:到达时间 服务时间 完成时间 周转时间 带权周转时间 ");
sum1=0;
sum2=0;
switch(px)
{
case 2:
{
for(i=0;i<n;i++)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
case 1:
{
for(j=0;j<n;j++)
{ for(i=0;i<n;i++)
if(a[i].id==j+1)
{
printf("%d: %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
default: break;
}
}
void yxj()
{
int i,j,n,min,px;
int b=0,z;
float sum1,sum2;
printf(" 请输入有n个进程(0<n<=50): ");
scanf("%d/n",&n);
while(n>50||n<=0)
{
printf("n 请重新输入: ");
scanf("%d",&n);
}
printf(" ");
struct Gzuo{
int id; //进程名字
int dt; //到达时刻
int st; //服务时间
int yxj; //优先级
int wct; //完成时刻
float zt; //周转时间
float dczt; //带权周转时间
};
Gzuo a[N];
for(i=0;i<n;i++)
{
a[i].id=i+1;
printf(" 到达时间: ");
scanf("%d",&a[i].dt);
printf(" 服务时间: ");
scanf("%d",&a[i].st);
printf(" 优先级: ");
scanf("%d",&a[i].yxj);
printf(" ");
}
min=a[0].dt;
for(j=n-1;j>=0;j--)
{
for(i=0;i<j;i++)
{
if(a[i].dt>a[i+1].dt)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
min=a[i].yxj;
a[i].yxj=a[i+1].yxj;
a[i+1].yxj=min;
}
if(a[i].dt==a[i+1].dt&&a[i].yxj<a[i+1].yxj)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
min=a[i].yxj;
a[i].yxj=a[i+1].yxj;
a[i+1].yxj=min;
}
}
}
a[0].wct=a[0].st+a[0].dt;
a[0].zt=(float)a[0].st;
a[0].dczt=a[0].zt/a[0].st;
for(i=1;i<n;i++)
{
if(a[i].dt>a[0].wct) ;
else b++;
}
for(j=b-1;j>=1;j--)
{
for(i=1;i<j;i++)
{
if(a[i].yxj<a[i+1].yxj)
{
min=a[i].dt;
a[i].dt=a[i+1].dt;
a[i+1].dt=min;
min=a[i].st;
a[i].st=a[i+1].st;
a[i+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
min=a[i].yxj;
a[i].yxj=a[i+1].yxj;
a[i+1].yxj=min;
}
}
}
for(i=1;i<n;i++)
{
if(a[i].dt>a[i-1].wct)
{
a[i].wct=a[i].dt+a[i].st;
a[i].zt=(float)a[i].st;
a[i].dczt=a[i].zt/a[i].st;
}
else
{
a[i].wct=a[i-1].wct+a[i].st;
a[i].zt=(float)(a[i].wct-a[i].dt);
a[i].dczt=a[i].zt/a[i].st;
}
for(j=i+1,b=j;j<n;j++)
{
if(a[j].dt>a[i].wct) ;
else b=b+1;
}
for(j=b-1;j>=i;j--)
{
for(z=i;z<j;z++)
{
if(a[z].yxj<a[z+1].yxj)
{
min=a[z].dt;
a[z].dt=a[z+1].dt;
a[z+1].dt=min;
min=a[z].st;
a[z].st=a[z+1].st;
a[z+1].st=min;
min=a[i].id;
a[i].id=a[i+1].id;
a[i+1].id=min;
}
}
}
}
printf(" 请选择输出顺序 ");
printf(" 1、按id号依次输出 ");
printf(" 2、按完成顺序依次输出 ");
scanf("%d",&px);
printf(" id:到达时间 服务时间 优先级 完成时间 周转时间 带权周转时间 ");
sum1=0;
sum2=0;
switch(px)
{
case 2:
{
for(i=0;i<n;i++)
{
printf("%d: %d %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].yxj,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
case 1:
{
for(j=0;j<n;j++)
{ for(i=0;i<n;i++)
if(a[i].id==j+1)
{
printf("%d: %d %d %d %d %.0f %.2f ",a[i].id,a[i].dt,a[i].yxj,a[i].st,a[i].wct,a[i].zt,a[i].dczt);
sum1+=a[i].zt;
sum2+=a[i].dczt;
}
}
printf(" 平均周转时间:%.2f ",sum1/n);
printf(" 平均带权周转时间:%.2f ",sum2/n);
break;
}
default: break;
}
}
五、实验截图
六、 实验总结
此次调度系统程序花了我不少时间去研究,本来是一窍不通的,后面是一步一步摸索,通过跟同学讨论还有参考网上才完成的,但是感觉这个程序还是存在一些BUG需要改进的,做得不是太好,希望下次能够做得更好。通过此次的编写系统也让我重拾C语音的程序编写能力,有一段时间没怎么写C语言程序会忘记不少东西,所以说接下来应该多去复习,并且学习新的知识才行!
---恢复内容结束---