进程调度算法 C C++
- 一、先来先服务
- 1.1 代码
- 1.2 运行截图
- 二、短进程优先
- 2.1 代码
- 2.2 运行截图
- 三、时间片轮转
- 3.1 代码
- 3.2 运行截图
- 四、多级队列
一、先来先服务
1.1 代码
#include <stdio.h>
#include <string.h>
double avg_TurnaroundTime;//平均周转时间
double AQTT;//平均带权周转时间
struct progress{
char proName[80];
int arriveTime;//到达时间
int serviceTime;//服务时间
//int flag; //访问标志,未访问1,访问0
int finishTime;//完成时间
int cyclingTime;//周转时间
double float_Wi;//带权周转时间
};
struct progress course[80];
//struct progress course[80]={{0,4},{1,3},{2,5},{3,2},{4,4}};
void health_Examine(int *courseNum)//输入合法性检查
{return; }
void progressNum(int *courseNum)//进程数目
{int i=0;
for(i=0; i<*courseNum;i++){
printf("请输入第%d个进程的相应信息。\n", i+1);
printf("请输入进程名:");
scanf("%s", course[i].proName);
printf("请输入到达时间:");
scanf("%d", &course[i].arriveTime);
printf("请输入服务时间:");
scanf("%d", &course[i].serviceTime); }
return;
}
void finish_Time(int *courseNum)//进程的完成时间
{int i=0;
if(course[0].arriveTime != 0)//第一个进程的时间
{course[0].finishTime=course[0].arriveTime + course[0].serviceTime; }
course[0].finishTime=course[0].serviceTime;
for(i=1; i<*courseNum; i++){
if(course[i-1].finishTime >= course[i].arriveTime) {
course[i].finishTime=course[i-1].finishTime + course[i].serviceTime;
}else{
course[i].finishTime=course[i].arriveTime + course[i].serviceTime;
}
}
return;
}
void cyclingTime(int *courseNum)//周转时间
{int i=0;
for(i=0; i<*courseNum; i++) {
course[i].cyclingTime=course[i].finishTime - course[i].arriveTime;
}
return;
}
void float_Wi(int *courseNum)//带权周转时间
{int i=0;
for(i=0; i<*courseNum; i++){
course[i].float_Wi=(double)course[i].cyclingTime/course[i].serviceTime;
}
return;
}
void avgTurnaroundTime(int *courseNum)//平均周转时间
{ int i=0,sum_TurnaroundTime=0;
for(i=0; i<*courseNum; i++){
sum_TurnaroundTime += course[i].cyclingTime;
}
avg_TurnaroundTime=sum_TurnaroundTime/(*courseNum);
return;
}
void _AQTT(int *courseNum)//平均带权周转时间
{int i=0;
double sum_float_Wi=0;
for(i=0; i<*courseNum; i++){
sum_float_Wi += course[i].float_Wi;
}
AQTT=sum_float_Wi/(*courseNum);
return;
}
void print_FIFO(int *courseNum)//输出进程相关的信息
{int i=0;
printf("进程的相应信息。\n");
printf("进程\t到达时间\t服务时间\t完成时间\t周转时间\t带权周转\n");//
for(i=0; i<*courseNum;i++) {
//printf("第%个进程的相应信息。\n", i+1);
printf("%s\t %d\t\t %d\t\t %d\t\t %d\t\t %.002lf\t\t\n", course[i].proName,course[i].arriveTime, course[i].serviceTime,course[i].finishTime,course[i].cyclingTime,course[i].float_Wi);
//putchar('\n');
}
printf("平均周转时间\t平均带权周转时间\n");
printf(" %.002lf\t\t %.002lf\n",avg_TurnaroundTime,AQTT);
return;
}
int main(){
int courseNum=5;
printf("请输入进程数:");
scanf("%d", &courseNum);
progressNum(&courseNum);//
finish_Time(&courseNum);//进程的完成时间
cyclingTime(&courseNum);//周转时间
float_Wi(&courseNum);//带权周转时间
avgTurnaroundTime(&courseNum);//平均周转时间
_AQTT(&courseNum);//平均带权周转时间
print_FIFO(&courseNum);//
return 0;
}
1.2 运行截图
二、短进程优先
2.1 代码
#include <stdlib.h>
#include <stdio.h>
//定义一个结构体:PCB
typedef struct PCB{
char processName[10]; //进程名
float arriveTime; //到达时间
float serviceTime; //服务时间
float startTime; //开始执行时间
float finishTime; //结束时间
float turnroundTime; //周转时间
float weightedTurnaroundTime; //带权周转时间
}pcb;
//输入进程信息,将N个进程的信息写入PCB型数组
void input(pcb *p,int N)
{
int i;
printf("\n");
printf("请输入进程的名字 到达时间 服务时间: (例如: A 0 100)\n");
for(i=0; i <= N-1; i++)
{
printf("请输入进程%d的信息:", i+1);
scanf("%s", &p[i].processName);
scanf("%f", &p[i].arriveTime);
scanf("%f", &p[i].serviceTime);
}
}
//对服务先后优先级排序
void sort(pcb *p, int N)
{
/*
1、对pcb型数组中的元素进行一个简单的排序
找到优先级最高的进程
并把其他进程也进行简单排序,方便后续工作
*/
//排序: N次循环,每次找到从i到N-1中优先级最高的进程,放到p[i]
int i,j,m,n,k;
for(i=0;i<=N-1;i++)
{
//循环比较剩余的变量 //排序后:从0~N-1 arriveTime增加 , arriveTime相同时, serviceTime短的优先
for(j=i+1;j<N;j++)
{
if(p[i].arriveTime>p[j].arriveTime || (p[i].arriveTime==p[j].arriveTime && p[i].serviceTime>p[j].serviceTime) )
{
//p[j]的优先级高于p[i],因此把p[j]放到p[i]
pcb temp;
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
//2、每个进程运行完成之后,找到当前时刻已经到达的最短进程P[0]优先级最高,
for(m=0; m<N-1; m++)
{
if(m == 0)
p[m].finishTime = p[m].arriveTime + p[m].serviceTime;
else
p[m].finishTime = ((p[m-1].finishTime >= p[m].arriveTime)? p[m-1].finishTime: p[m].arriveTime) + p[m].serviceTime;
//(1)找到p[m].finishTime时刻哪些进程已经到达
int i=0; //i统计 p[m].finishTime时刻有几个进程已经到达
//从下一个进程p[m+1]开始寻找
for(n = m+1; n <= N-1; n++)
{
if(p[n].arriveTime <= p[m].finishTime)
i++;
else
break;
/*由于在第1步已经对进程按照到达时间进行了排序
故:当p[n].arriveTime > p[m].finishTime时,
说明p[n]进程和其后面的其他进程都未到达。
i的值为p[m].finishtime时刻已经到达的进程数目。
*/
}
//(2)找到p[m].finishTime时刻已经到达的最短进程
float min = p[m+1].serviceTime; //next进程服务时间为p[m+1].serviceTime (初值)
int next = m+1; //next进程为m+1 (初值)
//p[m+1]至p[m+i]这i个已到达进程中找到最短进程
for(k = m+1; k < m+i; k++) //k为m+1 ~ m+i-1
{
//min的初值是p[m+1].serviceTime, k+1为m+2 ~m+i
if(p[k+1].serviceTime < min)
{
min = p[k+1].serviceTime;
next = k+1;
}
}
//(3)把最短进程放在p[m+1]进程处
pcb temp;
temp=p[m+1];
p[m+1]=p[next];
p[next]=temp;
}
}
//运行
void run(pcb *p, int N)
{
int k;
//计算各进程的开始时间和结束时间
for(k=0; k <= N-1; k++)
{
if(k==0) //第1个进程
{
p[k].startTime = p[k].arriveTime; //第1个进程到达之后即可执行
p[k].finishTime = p[k].startTime + p[k].serviceTime;
}
else
{
p[k].startTime = (p[k-1].finishTime >= p[k].arriveTime)? p[k-1].finishTime: p[k].arriveTime;
p[k].finishTime = p[k].startTime + p[k].serviceTime;
}
}
//计算各进程的周转时间和带权周转时间
for(k=0; k<=N-1; k++)
{
p[k].turnroundTime = p[k].finishTime - p[k].arriveTime;
p[k].weightedTurnaroundTime = p[k].turnroundTime / p[k].serviceTime;
}
}
//打印结果
void Print(pcb *p, int N)
{
int k;
printf("\n调用最短进程优先算法以后进程运行的顺序是: ");
printf("%s",p[0].processName);
for(k=1;k<N;k++)
{
printf("-->");
printf("%s", p[k].processName);
}
printf("\n");
printf("具体进程调度信息:\n");
printf("进程名 到达时间 服务时间 开始时间 结束时间 周转时间 带权周转时间\n");
for(k=0; k<=N-1; k++)
{
printf("%4s", p[k].processName);
printf("%10.3f", p[k].arriveTime);
printf("%10.3f", p[k].serviceTime);
printf("%10.3f", p[k].startTime);
printf("%10.3f", p[k].finishTime);
printf("%10.3f", p[k].turnroundTime);
printf("%10.3f\n", p[k].weightedTurnaroundTime);
}
}
//短进程优先
void sjff(pcb *p,int N)
{
sort(p, N);
run(p, N);
Print(p, N);
int k;
float atTime = 0; // 平均周转时间
float AQTTime = 0; //平均带权周转时间
for(k=0; k<=N-1; k++)
{
atTime += p[k].turnroundTime;
AQTTime += p[k].weightedTurnaroundTime;
}
atTime = atTime/N;
AQTTime = AQTTime/N;
printf("\n调用短进程优先算法的平均周转时间为:");
printf("%.3f\n", atTime);
printf("调用短进程优先算法的平均带权周转时间为:");
printf("%.3f\n", AQTTime);
}
int main()
{
pcb a[50];
int N; //进程数目
printf("\n");
printf("\n");
printf("输入进程数目:");
scanf("%d", &N);
input(a, N);
sjff(a, N);
return 0;
}
2.2 运行截图
三、时间片轮转
3.1 代码
#include<stdio.h>
#define N 50
struct PCB
{
int pn; //process name进程名字
int at; //arrival time到达时间
int st; //service time服务时间
int ct; //completion time完成时刻
int sc; //sign completion标志是否完成
int st1; //剩余服务时间
}process[N];
int sjp(int n)
{
int i,j,T;
printf("\n请输入时间片:\n");
scanf("%d",&T);
for(i=1;i<=n;i++) //收集进程信息
{
process[i].sc=0;
printf("\n%d:\n请依次输入进程的信息\n请输入pn:",i);
scanf("%d",&process[i].pn);
printf("请输入at:");
scanf("%d",&process[i].at);
printf("请输入st:");
scanf("%d",&process[i].st);
process[i].st1=process[i].st;
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++) //按照各进程到达时间升序,对进程排序 注意:稳定的排序
{
if(process[j].at<process[i].at)
{
process[0]=process[j];
process[j]=process[i];
process[i]=process[0];
}
}
//for(i=1;i<=n;i++) //检查排序是否正确
//printf("%d\t",process[i].pn);
int time=process[1].at; //当前时间的初值
int flag=1;
int sum=0; //记录完成的进程数
printf("\n第几次调度进程 运行的进程pn 开始运行时间 运行时间 剩余服务时间 结束时间\n");
int z=1; //记录第几次调度进程
while(sum<n)
{
flag=0; //标志就绪队列中是否还有进程
for(i=1;i<=n;i++) //时间片轮转法执行各进程
{
if(process[i].sc==1) continue; //已完成的进程
else
{
if(process[i].st1<=T&&time>=process[i].at)//未完成的进程但是还需服务的时间少于等于一个时间片
{
flag=1;
time=time+process[i].st1;
process[i].sc=1;
process[i].ct=time;
printf("%8d%12d%15d%11d%11d%11d\n",z++,process[i].pn,time-process[i].st1,process[i].st1,0,time);
process[i].st1=0;
}
else if(process[i].st1>T&&time>=process[i].at)//未完成的进程但其还需服务时间至少大于一个时间片
{
flag=1;
time=time+T;
process[i].st1-=T;
printf("%8d%12d%15d%11d%11d%11d\n",z++,process[i].pn,time-T,T,process[i].st1,time);
}
if(process[i].sc==1) sum++; //一个进程执行完就+1
}
}
if(flag==0&&sum<n) // 还有没执行的进程,且没进入就就绪队列
{
for(i=1;i<=n;i++)
if(process[i].sc==0) {time=process[i].at;break;}
}
}
}
int main()
{
int n;
printf("\t\t时间片轮转调度算法\n");
printf("请输入总进程数:\n");
scanf("%d",&n);
sjp(n);
return 0;
}
3.2 运行截图
四、多级队列