调度算法
-
先来先服务
-
优先级调度(这里是非抢占)(第一个到达的肯定要先执行)
-
短作业优先(第一个到达的肯定要先执行)
-
时间片轮转
时间片轮转和先来先服务的区别就是前者也是先来先服务,但是给你三分钟的时间片你要是干不完一碗饭就排到最后面,等一下接着吃
实验模拟如下
进程ID | arrivetime | servicetime | priority |
---|---|---|---|
1 | 1 | 9 | 2 |
2 | 4 | 6 | 3 |
3 | 5 | 3 | 1 |
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define max 50
struct PCB
{
int name;
int arrivetime; //到达时间
int servicetime; //服务时间
int finishtime; //完成/结束时间
int turntime; //周转时间
int average_turntime; //带权周转时间
int sign; //标志进程是否完成,用于后续时间片轮转中
int remain_time; //剩余时间
int priority; //优先级
}pcb[max];//顺便定义进程数组pcb
void init(int n) //初始化;这里不使用0号位置即(进程1对应下标1);0号位作为中间容器
{
int i;
for(i=1;i<=n;i++)
{
pcb[i].arrivetime=0;
pcb[i].servicetime=0;
pcb[i].finishtime=0;
pcb[i].turntime=0;
pcb[i].average_turntime=0;
pcb[i].remain_time=0;
pcb[i].sign=0;
pcb[i].priority=0;
}
}
void creat(int n) //创建PCB
{
int i;
//若n为3,则对下标1,2,3进行设置进程PCB
for(i=1;i<=n;i++)
{
printf("
%d:
input the information of process
input processID:",i);
scanf("%d",&pcb[i].name);
printf(" input the arrivetime:");
scanf("%d",&pcb[i].arrivetime);
printf(" input the servicetime:");
scanf("%d",&pcb[i].servicetime);
printf(" input the priority:");
scanf("%d",&pcb[i].priority);
pcb[i].remain_time=pcb[i].servicetime; //初始化剩余时间为服务时间
}
}
void FCFS(int n) //先来先服务
{
int starttime;
//先设置一个开始时间,有两种情况:
//1:开始时间和第一个的进程到达时间一样,即“来了就让它执行”
//2:如果第一进程的到达时间还没到达设置的starttime,就让它等会,等到starttime这个时间点了再让它先执行
//其他的调度不用设置开始时间,因为第一个来的先执行
printf("
input the start time:");
scanf("%d",&starttime);
if(starttime>=pcb[1].arrivetime)
{
pcb[1].finishtime=pcb[1].servicetime+starttime;
}
else
{
pcb[1].finishtime=pcb[1].arrivetime+pcb[1].servicetime;
}
int i;
//计算剩下进程的finishtime
for(i=2;i<=n;i++)
{
if(pcb[i-1].finishtime>pcb[i].arrivetime)
pcb[i].finishtime=pcb[i-1].finishtime+pcb[i].servicetime;
else
pcb[i].finishtime=pcb[i].arrivetime+pcb[i].servicetime;
}
//计算每一个进程的周转时间和带权周转时间
for(i=1;i<=n;i++)
{
pcb[i].turntime=pcb[i].finishtime-pcb[i].arrivetime;
pcb[i].average_turntime=pcb[i].turntime/pcb[i].servicetime;
}
}
void print_FCFS(int n)
{
printf("process ID arrivetime servicetime finishtime turntime averageturntime .
");
int i;
//第一个进程从下标1开始
for(i=1;i<=n;i++)
{
printf("%6d%11d%12d%12d%10d%12d",pcb[i].name ,pcb[i].arrivetime ,pcb[i].servicetime ,pcb[i].finishtime ,pcb[i].turntime ,pcb[i].average_turntime);
printf("
");
}
}
void time_segment(int n) //时间片轮转,在时间片轮转中只需要remain_time来表示一个进程需要的时间
{
int i,j;
int T; //时间片长度
int flag=1; //就绪队列中是否还有进程
int time=0;
int sum=0; //已经完成的进程数
//按各进程的arrivetime进行升序排列
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(pcb[j].arrivetime<pcb[i].arrivetime)
{
pcb[0]=pcb[j];
pcb[j]=pcb[i];
pcb[i]=pcb[0];
}
}
time=pcb[1].arrivetime;//时间轴初始值
printf("
input the slicetime:");
scanf("%d",&T);
while(sum<n)
{
flag=0; //当前就绪队列中没有进程
int i;
for(i=1;i<=n;i++)
{
if(pcb[i].sign==1) continue; //表示该进程已完成
else
{
//没有完成的进程需要的时间大于一个时间片
if(pcb[i].remain_time > T)
{
flag=1;
time=time+T;
pcb[i].remain_time=pcb[i].remain_time-T;
}
//没有完成的进程需要的时间小于或等于一个时间片(在这种情况下才有finishtime)
else if(pcb[i].remain_time <= T)
{
flag=1; //加入就绪队列
time=time+pcb[i].remain_time;
pcb[i].finishtime=time;
pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;
pcb[i].sign=1;//进程完成标志sign,即退出就绪队列
pcb[i].remain_time=0;//及时归零
}
if(pcb[i].sign==1) sum++;
}
}//for
if(flag==0&&sum<n) // 还有没执行的进程,且没进入就就绪队列
{
int i;
for(i=1;i<=n;i++)
if(pcb[i].sign==0) {time=pcb[i].arrivetime;break;}//如果有没执行的进程,时间轴置放到它的到达时间上
}
}//while
}
void print_time(int n)
{
int i;
for(i=1;i<=n;i++)
{
printf("
processID runtime fihishtime turntime average_turntime
");//进程名 服务时间 优先级 完成时间
printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
printf("
");
}
}
void Priority(int n)
{
int i,j;
int time = pcb[1].arrivetime;
//按各进程的arrivetime进行升序排列,最早到达的进程先执行
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(pcb[j].arrivetime < pcb[i].arrivetime)
{
pcb[0]=pcb[j];
pcb[j]=pcb[i];
pcb[i]=pcb[0];
}
}
printf("
processID runtime priority fihishtime
");//进程名 服务时间 优先级 完成时间
//先到达的进程第一个执行
if(i=1)
{
pcb[i].finishtime=pcb[i].arrivetime + pcb[i].servicetime;
time =pcb[i].arrivetime + pcb[i].servicetime;
printf("%6d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].priority,pcb[i].finishtime);
printf("
");
i++;
}
//按各进程的priority进行降序排列,优先级最高的进程先执行
for(i=2;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(pcb[j].priority > pcb[i].priority)
{
pcb[0]=pcb[j];
pcb[j]=pcb[i];
pcb[i]=pcb[0];
}
}
for(i=2;i<=n;i++)
{
time = time + pcb[i].servicetime;
pcb[i].finishtime = time;
printf("%6d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].priority,pcb[i].finishtime);
printf("
");
}//for
}//void
void SJF(int n)//短作业优先并输入进程个数
{
int i,j;
int time = pcb[1].arrivetime;//时间轴以第一个进程的到达时间为起点
//按各进程的arrivetime进行升序排列,但最早到达的进程毋庸置疑先执行
//只要有前后关系就有双重for循环
//目的求出第一个到达的进程在pcb[1]里
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(pcb[j].arrivetime < pcb[i].arrivetime)
{
pcb[0]=pcb[j];
pcb[j]=pcb[i];
pcb[i]=pcb[0];
}
}
printf("
processID runtime fihishtime turntime average_turntime
");//进程名 服务时间 优先级 完成时间
//先到达的进程第一个执行
if(i=1)
{
pcb[i].finishtime=pcb[i].arrivetime + pcb[i].servicetime;
time =pcb[i].arrivetime + pcb[i].servicetime;
pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;
printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
printf("
");
i++;
}
//按各进程的服务时间进行升序排列,servicetime越短的进程先执行
for(i=2;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(pcb[j].servicetime < pcb[i].servicetime)
{
pcb[0]=pcb[j];
pcb[j]=pcb[i];
pcb[i]=pcb[0];
}
}
//对排序后的进程序列进行计算
for(i=2;i<=n;i++)
{
time = time + pcb[i].servicetime;
pcb[i].finishtime = time;
pcb[i].turntime=pcb[i].finishtime - pcb[i].arrivetime;
pcb[i].average_turntime = pcb[i].turntime/pcb[i].servicetime;
printf("%6d%10d%10d%10d%10d",pcb[i].name,pcb[i].servicetime,pcb[i].finishtime,pcb[i].turntime,pcb[i].average_turntime);
printf("
");
}//for
}
void layout(int n)
{
int i;
for(i=0;;i++)
{
int ch=0;
printf("
");
printf(" ************schedule algorithm************
");
printf(" 1.FSFS
");
printf(" 2.timesegment
");
printf(" 3.priority
");
printf(" 4.SJF
");
printf(" 5.Esc
");
printf(" choose the algorithm:");
scanf("%10d",&ch);
switch(ch)
{
case 1:
FCFS(n);
print_FCFS(n); break;
case 2:
time_segment(n);
print_time(n); break;
case 3:
Priority(n); break;//print代码段已内置
case 4:
SJF(n);break;//print代码段已内置
case 5:
exit(0);
default:printf("enter error data!
");
//P:int类型的变量,case后面不要加''
}
}
}
int main()
{
int n;
printf("Input the number of process: ");
scanf("%d",&n);
init(n);//初始化pcb数组为零
creat(n);//根据输入信息更改pcb数组
layout(n);
return 0;
}
结果如下图