- 1.SPN算法思想
短作业优先(Shortest Process Next,SPN)的调度算法,由于在实际情况中,短进程(作业)占有很大比例,为了能使它们能比长进程(作业)优先执行,而产生了短进程(作业)优先调度算法。
算法思想:从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行。
SPN调度算法较之FCFS算法有了明显的改进,但仍然存在不容忽视的缺点:
(1) 必须预知作业的运行时间。在采用这种算法时,要先知道每个作业的运行时间。即使是程序员也很难准确估计作业的运行时间,如果估计过低,系统就可能按估计的时间终止作业的运行,但此时作业并未完成,故一般都会偏长估计。
(2) 对长作业非常不利,长作业的周转时间会明显地增长。更严重的是,该算法完全忽视作业的等待时间,可能使作业等待时间过长,出现饥饿现象。
(3) 在采用FCFS算法时,人-机无法实现交互。
(4) 该调度算法完全未考虑作业的紧迫程度,故不能保证紧迫性作业能得到及时处理。
- 2.代码模拟实现
#include<bits/stdc++.h>//万能头文件
using namespace std;
struct job
{
char name[10];//作业的名字
int starttime;//作业到达时间
int needtime;//作业服务时间
int runtime;//作业周转时间
int endtime;//作业结束时间
double dqzz_time;//带权周转时间
bool finished;//作业完成标志
};
bool campare_start(struct job job1,struct job job2)//自定义排序方式,按到达顺序从大到小排,保证jobs[0]为第一个到达的进程
{
return job1.starttime<job2.starttime;
}
void print_SPN(struct job jobs[50],int n)
{
double a_runtime=0;//平均周转时间
double a_dqzz_time=0;//平均带权周转时间
double sum_time1=0;//总周转时间
double sum_time2=0; //总带权周转时间
for(int i=0;i<n;i++)
{
cout<<"作业名:"<<jobs[i].name<<" 到达时间:"<<jobs[i].starttime<<" 运行时间:"<<jobs[i].needtime<<" 完成时间:"
<<jobs[i].endtime<<" 周转时间"<<jobs[i].runtime<<" 带权周转时间:"<<jobs[i].dqzz_time<<endl;
sum_time1+=jobs[i].runtime;
sum_time2+=jobs[i].dqzz_time;
}
a_runtime=sum_time1/n;
a_dqzz_time=sum_time2/n;
cout<<"平均周转时间"<<a_runtime<<endl;
cout<<"平均带权周转时间"<<a_dqzz_time<<endl;
}
void SPN(struct job jobs[50],int n)
{
int last_finished_index; //记录上一次已经运行的进程的数组下标
jobs[0].endtime=jobs[0].starttime+jobs[0].needtime;//完成时间
jobs[0].runtime=jobs[0].endtime-jobs[0].starttime;//周转时间
jobs[0].dqzz_time=double(jobs[0].runtime)/jobs[0].needtime;//带权周转时间
jobs[0].finished=true;
last_finished_index=0;
int index;//保存每次最短服务时间进程的索引。
int min_time;
int job_endtime;//保存上一进程的结束时间
for(int i=1;i<n;i++)
{
min_time=1000;//1.初始化,防止min-time太小,影响查找最短服务时间的进程.
job_endtime=jobs[last_finished_index].endtime;
index=-1;//初始化,可用来判断所有进程是否完成
for(int j=1;j<n;j++)//找到最短服务时间的进程
{
if(min_time>jobs[j].needtime&&jobs[j].finished==false&&job_endtime>=jobs[j].starttime)
//上一进程的结束时间,应该在进程A到达时间之后,进程A才能进就绪队列,才能参与排序
{
min_time=jobs[j].needtime;
index=j;
}
}
jobs[index].endtime=jobs[last_finished_index].endtime+jobs[index].needtime;//完成时间
jobs[index].runtime=jobs[index].endtime-jobs[index].starttime;//周转时间
jobs[index].dqzz_time=double(jobs[index].runtime)/jobs[index].needtime;//带权周转时间
jobs[index].finished=true;
last_finished_index=index;
if(last_finished_index==-1)//所有进程已完成,退出
{
break;
}
}
}
int main()
{
struct job jobs[50];
int n;//n个作业
cout<<"请输入作业个数"<<endl;
cin>>n;
cout<<"请输入各作业的信息(作业名 到达时间 服务时间):"<<endl;
for(int i=0;i<n;i++)
{ cin>>jobs[i].name;
cin>>jobs[i].starttime;
cin>>jobs[i].needtime;
}
SPN(jobs,n);//调用SPN算法
cout<<"SPN调度算法运行结果:"<<endl;
print_SPN(jobs,n); //打印SPN运行结果
return 0;
}
- 3.运行结果