C语言实现先来先服务(FCFS)和短作业优先(SJF)进程调度算法。
要求输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
短作业优先(SJF)算法是以进入系统的作业所要求的CPU时间为标准,是指对短作业或者短进程优先调度的算法,将每个进程与其估计运行时间进行关联选取估计计算时间最短的作业投入运行。
代码自己写的,并没有很完善,输入做的是最简单的,更细化的还要自己改一下。
①定义好变量
#include<stdio.h>
#include<string.h>
struct job{
char name[10]; //作业的名字
int starttime; //作业到达系统时间
int needtime; //作业服务时间
int runtime; //作业周转时间
int endtime; //作业结束时间
double dqzztime; //带权周转时间
};
void fcfs(struct job jobs[50],int n);
void sjf(struct job jobs[50],int n);
void result(struct job jobs[50],int n);
②main函数
void main()
{
struct job jobs[50];
int n,i; //n个作业
printf("输入作业个数:");
scanf("%d",&n);
printf("输入每个作业的作业名,到达时间,服务时间:\n");
for(i=0;i<n;i++)
{
scanf("%s",jobs[i].name); //作业名
scanf("%d",&jobs[i].starttime);//到达时间
scanf("%d",&jobs[i].needtime);//运行(服务时间)时间
}
printf("\n");
printf("作业名\t到达系统时间\t运行时间\n");
for(i=0;i<n;i++)
{
printf("%s\t %d\t %d\n",jobs[i].name,jobs[i].starttime,jobs[i].needtime);
}
fcfs(jobs,n);
printf("先来先服务(FCFS)算法运行结果:\n");
result(jobs,n);
sjf(jobs,n);
printf("最短作业优先算法(SJF)运行结果:\n");
result(jobs,n);
}
③FCFS
void fcfs(struct job jobs[50],int n)
{
int i;
for(i=0;i<n;i++)
{
if(i==0) { //第一个进程
jobs[i].runtime=jobs[i].needtime; //周转时间=服务时间
jobs[i].endtime=jobs[i].starttime+jobs[i].needtime;//结束时间=到达时间+服务时间
}
else if(jobs[i].starttime>jobs[i-1].endtime){ //第i个进程到达系统时,第i-1个进程已运行完毕
jobs[i].runtime=jobs[i].needtime;
jobs[i].endtime=jobs[i].starttime+jobs[i].needtime;
}
else{ //第i个进程到达系统时,第i-1个进程未运行完毕
jobs[i].runtime=jobs[i].needtime+jobs[i-1].endtime-jobs[i].starttime; //周转时间=服务时间+前一个的结束时间-到达时间
jobs[i].endtime=jobs[i].starttime+jobs[i].runtime;//结束时间=到达时间+周转时间
}
jobs[i].dqzztime=jobs[i].runtime*1.0/jobs[i].needtime; //带权周转时间=周转时间/服务时间
}
}
④SJF
void sjf(struct job jobs[50],int n)
{
int i=0,b=0;
char temp[10];
int min;
for(i=0;i<n-1;i++) //按作业到达系统时间进行排序,最早到达的排在最前面
{
if(jobs[i].starttime>jobs[i+1].starttime)
{ //把到达时间早的赋值到min
min=jobs[i].starttime;
jobs[i].starttime=jobs[i+1].starttime;
jobs[i+1].starttime=min;
//把到达时间早的赋值到min
min=jobs[i].needtime;
jobs[i].needtime=jobs[i+1].needtime;
jobs[i+1].needtime=min;
strcpy(temp,jobs[i].name);
strcpy(jobs[i].name,jobs[i+1].name);
strcpy(jobs[i+1].name,temp);//在temp数组中排序
}
}
jobs[0].endtime=jobs[0].starttime+jobs[0].needtime;//结束时间=到达时间+服务时间
jobs[0].runtime=jobs[0].needtime;//周转时间=服务时间
jobs[0].dqzztime=jobs[0].runtime*1.0/jobs[0].needtime;//带权周转时间=周转时间/服务时间
for(i=1;i<n;i++)
{
if(jobs[i].starttime>jobs[0].endtime) ; //作业到达系统时,第0个作业还在运行
else b=b+1; //用b统计需等待作业0运行的作业个数
}
for(i=1;i<=b-1;i++)
{
if(jobs[i].needtime>jobs[i+1].needtime)
{
min=jobs[i].starttime;
jobs[i].starttime=jobs[i+1].starttime;
jobs[i+1].starttime=min;
min=jobs[i].needtime;
jobs[i].needtime=jobs[i+1].needtime;
jobs[i+1].needtime=min;
strcpy(temp,jobs[i].name); //将第二个参数的值复制给第一个参数,返回第一个参数
strcpy(jobs[i].name,jobs[i+1].name);
strcpy(jobs[i+1].name,temp);
} //按最短运行时间排序
}
for(i=1;i<n;i++)
{
if(jobs[i].starttime>jobs[i-1].endtime)
{ //第i个进程到达系统时,第i-1个进程已运行完毕
jobs[i].endtime=jobs[i].starttime+jobs[i].needtime;
jobs[i].runtime=jobs[i].needtime;
}
else
{
jobs[i].endtime=jobs[i-1].endtime+jobs[i].needtime;
jobs[i].runtime=jobs[i].endtime-jobs[i].starttime;
}
jobs[i].dqzztime=jobs[i].runtime*1.0/jobs[i].needtime;
}
}
⑤结果输出
void result(struct job jobs[50],int n)
{
int i;
double averruntime;
double averdqzztime;
int sum_runtime=0;
double sum_dqzztime=0.00;
printf("作业名\t到达时间\t运行时间\t完成时间\t周转时间 带权周转时间\n");
for(i=0;i<n;i++)
{
printf("%s\t %d\t %d\t %d\t %d %.2f\n",jobs[i].name,jobs[i].starttime,jobs[i].needtime,jobs[i].endtime,jobs[i].runtime,jobs[i].dqzztime);
sum_runtime=sum_runtime+jobs[i].runtime;
sum_dqzztime=sum_dqzztime+jobs[i].dqzztime;
}
averruntime=sum_runtime*1.0/n;
averdqzztime=sum_dqzztime*1.000/n;
printf("平均周转时间:%.2f \n",averruntime);
printf("平均带权周转时间:%.3f \n",averdqzztime);
printf("\n");
}
⑥输入数据测试
– 输入数据:
– 进程数n = 5
– 到达时间:0 1 2 3 4
– 服务时间:4 3 5 2 4