作业调度算法
1.先来先服务(FCFS)
1.1概念
先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
1.2代码实现
#include<stdio.h>
#include<stdlib.h>
struct fcfs //ID
{
char name[20];
float startime;
float arrivetime;
float servicetime;
float finishtime;
float zztime; //周转时间
float dqzztime; // 平均周转时间
};
void input(struct fcfs *p,int N)//输入进程相关信
{
printf("请输入进程的名字 到达时间 服务时间:(比如:进程1 0 10)\n");
int i;
for(i=1;i<=N;i++)
{
printf("请输入进程%d的信息:\n", i);//i的初始值设为1,这样方便表示
printf("名称: ");
scanf("%s",p[i-1].name);
printf("到达时间:");
scanf("%f",&p[i-1].arrivetime);
printf("所需cpu时间:");
scanf("%f",&p[i-1].servicetime);
printf("\n");
}
}
void sort(struct fcfs *p,int N){
int i,j;
for(i=0;i<N-1;i++)
{
for(j=0;j<N-i-1;j++)
{
if(p[j].arrivetime>p[j+1].arrivetime)
{
struct fcfs temp;
temp=p[j];
p[j]=p[j+1];
p[j+1]=temp;
}
}
}
}
void run(struct fcfs *p,int N){
int i;
for(i=0;i<N;i++)
{
if(i==0){
p[i].startime=p[i].arrivetime;
p[i].finishtime=p[i].arrivetime+p[i].servicetime;
//周转时间=要求服务时间+等待时间
p[i].zztime=p[i].servicetime;
//其他进程:p[i].zztime=p[i].finishtime-p[i].arrivetime;
p[i].dqzztime=p[i].zztime/p[i].servicetime;
}else{
p[i].startime=p[i-1].finishtime;
p[i].finishtime=p[i].startime+p[i].servicetime;
p[i].zztime=p[i].finishtime-p[i].arrivetime;
p[i].dqzztime=p[i].zztime/p[i].servicetime;
}
}
}
void show(struct fcfs *p,int N) {
int i;
printf("调用先来先服务算法后进程的运行顺序为:\n");
for(i=0;i<N;i++){
printf("%s",p[i].name);
printf("---->");
}
printf("\n");
printf("具体的进程调度信息为\n");
printf("进程 到达时间 服务时间 周转时间 ....\n");
for(i=0;i<N;i++){
printf("%3s",p[i].name);
printf("%8.3f",p[i].arrivetime);
printf("%8.3f",p[i].servicetime);
printf("%8.3f",p[i].zztime);
printf("\n");
}
}
int main()
{
struct fcfs a[100]; //创建100个结构体
int N; //进程数量
printf("请输入进程数目:");
scanf("%d",&N);
input(a,N);
sort(a,N);
run(a,N);
show(a,N);
int i;
float average_zztime=0;
float average_dqzztime=0;
for(i=0;i<N;i++){
average_zztime+=a[i].zztime;
average_dqzztime+=a[i].dqzztime;
}
average_zztime/=N;
average_dqzztime/=N;
printf("采用FCFS算法算得平均周转时间为:%f",average_zztime);
printf("采用FCFS算法算得平均带权周转时间为:%f",average_dqzztime);
return 0;
}
1.3实验结果
2.短进程优先(SJF)
2.1概念
短作业(进程)优先调度算法 优先调度算法SJ§F ,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它 ,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。
2.2代码实现
#include<stdio.h>
#include<stdlib.h>
struct sjf //ID
{
char name[20];
float startime;//进程开始时间
float arrivetime;//进程到达时间
float servicetime;//进程执行时间
float finishtime;//进程完成时间
float zztime; //周转时间
float dqzztime; // 平均周转时间
};
void input(sjf *p,int N)//输入进程相关信
{
printf("请输入进程的名字 到达时间 服务时间:(比如:进程1 0 10)\n");
for(int i=1;i<=N;i++)
{
printf("请输入进程%d的信息:\n", i);//i的初始值设为1,这样方便表示
printf("Process ID: ");
scanf("%s",p[i-1].name);
printf("Arrival Time: ");
scanf("%f",&p[i-1].arrivetime);
printf("Service Time: ");
scanf("%f",&p[i-1].servicetime);
printf("\n");
}
}
void sort_arrivetime(sjf *p,int N){//对所有进程按照到达时间进行排序
int i,j;
sjf temp;
for(i=0;i<N-1;i++)
{
for(j=0;j<N-i-1;j++)
{
if(p[j].arrivetime>p[j+1].arrivetime)
{
temp=p[j];
p[j]=p[j+1];
p[j+1]=temp;
}
}
}
}
void sort_servicetime(sjf *p,int N)//对start到i之间的进程进行排序
{
sjf temp;//创建一个零时进程,便于后期排序时进行交换
int k=0;
float end=0.0;//保存cpu已经运行的时间
for(int i=0;i<N;i++){
k=i;//保存当前i的下表
while(p[i].arrivetime<=end&&i<N)//对从第i个之后的所有进程进行搜索
i++;//找到最后一个等待进程的下标(其实就是当前在等待的最后一个进程)
for (int t=k; t<i; t++)//对当前正在等待执行的进程按照服务时间排序
{
for (int j = k+1; j<i; j++)
{
if(p[t].servicetime < p[j].servicetime)
continue;
else
{
temp = p[t];
p[t] = p[j];
p[j] = temp;
}
}
}
i=k; //将i的下标还原
end+=p[i].servicetime;
}
}
void run(sjf *p,int N){
int i;
for(i=0;i<N;i++)
{
if(i==0){
p[i].startime=p[i].arrivetime;
p[i].finishtime=p[i].arrivetime+p[i].servicetime;
//周转时间=要求服务时间+等待时间
p[i].zztime=p[i].servicetime;
//其他进程:p[i].zztime=p[i].finishtime-p[i].arrivetime;
p[i].dqzztime=p[i].zztime/p[i].servicetime;
}else{
p[i].startime=p[i-1].finishtime;
p[i].finishtime=p[i].startime+p[i].servicetime;
p[i].zztime=p[i].finishtime-p[i].arrivetime;
p[i].dqzztime=p[i].zztime/p[i].servicetime;
}
}
}
void show(sjf *p,int N) {
int i;
printf("调用短进程算法后进程的运行顺序为:\n");
for(i=0;i<N;i++){
printf("%s",p[i].name);
printf("---->");
}
printf("\n");
printf("具体的进程调度信息为\n");
printf("进程 到达时间 服务时间 周转时间 ....\n");
for(i=0;i<N;i++){
printf("%3s",p[i].name);
printf("%8.3f",p[i].arrivetime);
printf("%8.3f",p[i].servicetime);
printf("%8.3f",p[i].zztime);
printf("\n");
}
}
int main()
{
sjf a[100]; //创建100个结构体
int N; //进程数量
printf("请输入进程数目");
scanf("%d",&N);
input(a,N);//输入每个进程的信息
sort_arrivetime(a,N);//对所有进程按到达时间排序
sort_servicetime(a,N);//对当前的等待进程按照服务时间排序
run(a,N);//排好顺序之后,开学运行,计算结果
show(a,N);//展示结果
int i;
float average_zztime=0;
float average_dqzztime=0;
for(i=0;i<N;i++){
average_zztime+=a[i].zztime;
average_dqzztime+=a[i].dqzztime;
}
average_zztime/=N;
average_dqzztime/=N;
printf("采用SJF算法算得平均周转时间为:%f",average_zztime);
printf("采用SJF算法算得平均带权周转时间为:%f",average_dqzztime);
return 0;
}
2.3实验结果
3.1高响应比优先调度算法(HRRN)
3.1概念
在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。如果我们能为每个作业引入前面所述的动态优先权 ,并使作业的优先级随着等待时间的增加而以速率a提高,则长作业在等待一定的时间后,必然有机会分配到处理机。该优先权的变化规律 该优先权的变化规律可描述为:
优先权=(等待时间+要求服务时间)/要求服务时间=响应时间/要求服务时间
##等待时间=最后一个的提交时间-改作业到达的时刻。