1、先来先服务(first-come first-server)
它是最简单的非抢占式的进程调度算法,进程按照它们请求cpu的顺序使用cpu,当第一个作业从外部进入系统,就立即运行它所需要运行的时间。不会中断该作业。当其他作业进入时,它们就被安排到队列的尾部。当正在运行的进程被阻塞时,队列中的第一个进程接着运行。在被阻塞的进程重新变为就绪状态,排到队列的末尾,就像新来到的作业一样。
2、时间片轮转(RR)
它是一种最古老,最简单,最公平且使用最广的算法。每个进程被分配一个时间段,称它为时间片,即允许进程运行的时间。如果在时间片结束时进程还在进行,则cpu将被剥夺并分配给另一个进程。如果进程在结束前阻塞或结束,则cpu当即进行切换。当进程用完它的时间片后,它被移到队列的末尾。直到进程运行结束,它才从队列中移出。
以下代码演示了这两个进程调度算法,程序将从文件读取进程信息,在进程调度结束后,将调度结果输入到文件中
#include<stdio.h>
#include<stdlib.h>
#define N 50
struct PCB //定义进程控制块
{ int name; //进程名
int runFlag;//判断进程是否已结束
int startFlag;//判断进程是否是首次进行
int ArriveTime; //到达时间
int StartTime; //进程开始时间
int FinishTime; //进程结束时间
int ServiceTime; //服务时间
int serviceTime1; //还需服务的时间
float WholeTime;//周转时间
float WeightWholeTime;//带权周转时间
}pcbs[N];
double x=0,y=0;//用于统计总的周转时间,总的带权周转时间
int i;
int time=0; //计时器
int Round=2;//时间片
float averageWholeTime=0;//平均周转时间
float averageWeightWhole=0;//平均带权周转时间
int count_line(char* filepath){//统计文件里的进程数
int count=0;
int flag=0;
FILE *fp=fopen(filepath,"r");
if(!fp){
printf("can't open file!");
return 0;
}
while(!feof(fp)){
flag=fgetc(fp);
if(flag=='\n')count++;
}
int line=count+1;
return line;
}
int charge(){//判断是否全部进程都执行完毕
int k;
int n=count_line("C:\\Users\\12280\\Desktop\\进程.txt");//获取文件中有几个进程
int size=3*n;//文件里一行有3个数值,分别表示进程名,进程到达时间,进程运行时间,所以将3*行数,用于遍历所以完整的进程
int flag=0;
for(i=0;i<size;i+=3){
if(pcbs[i].runFlag==0){//判断进程是否已经结束
flag=1;
return flag;
break;
}else{
flag=0;
}
}
return flag;
}
void run_RR(){//时间片调度算法函数
int n=count_line("C:\\Users\\12280\\Desktop\\进程.txt");//获取文件中有几个进程
int size=3*n;//文件里一行有3个数值,分别表示进程名,进程到达时间,进程运行时间,所以将3*行数,用于遍历所以完整的进程
time=pcbs[i].ArriveTime;
while(charge())
{
for(i=0;i<size;i+=3){
if(pcbs[i].ArriveTime>time){//进程到达时间大于现在的时间,则进程从到达时间开始运行,否则从当前时间运行
time=pcbs[i].ArriveTime;
}
if(pcbs[i].runFlag==0){//判断进程是否结束,若已结束,则开始下一个进程,否则执行当前进程
if(pcbs[i].startFlag==0){
pcbs[i].StartTime=time;
pcbs[i].startFlag=1;
}
printf("--->时刻:%d, 正在运行的作业:%d\n",time,pcbs[i].name);
if(pcbs[i].serviceTime1>Round){
pcbs[i].serviceTime1=pcbs[i].serviceTime1-Round;//如果服务时间大于时间片,运行一次后,减去一个时间片的时间
time=time+Round;
}else if(pcbs[i].serviceTime1==Round){//如果剩余服务的时间刚刚好等于时间片的时间,则结束时间为当前时间加上时间片的时间
time=time+Round;
pcbs[i].FinishTime=time;
pcbs[i].runFlag=1;//并标志此进程已结束
}else{
time=pcbs[i].serviceTime1+time;//如果剩余服务的时间小于时间片的时间,则结束时间为当前时间加上剩余服务时间
pcbs[i].FinishTime=time;
pcbs[i].runFlag=1;//并标注此进程已结束
}
}
}
}
printf("hello");
}
int poutput() /*调度结果输出*/
{
int i;
int n=count_line("C:\\Users\\12280\\Desktop\\进程.txt");
int size=3*n;
FILE *fp=fopen("C:\\Users\\12280\\Desktop\\res.txt","a");
printf("进程名 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间\n");
for(i=0; i<3*n; i+=3)
{
pcbs[i].WholeTime=pcbs[i].FinishTime-pcbs[i].StartTime;
pcbs[i].WeightWholeTime=pcbs[i].WholeTime/pcbs[i].ServiceTime;
x+=pcbs[i].WholeTime;
y+=pcbs[i].WeightWholeTime;
printf("%4d %6d %6d %6d %6d %8.1f %10.1f\n",pcbs[i].name,pcbs[i].ArriveTime,pcbs[i].ServiceTime,pcbs[i].StartTime,pcbs[i].FinishTime,pcbs[i].WholeTime,pcbs[i].WeightWholeTime);
fprintf(fp,"进程名字=%4d 进程到达时间=%6d 进程服务时间=%6d 进程开始时间=%6d 进程结束时间=%6d 周转时间=%8.1f 带权周转时间=%10.1f\n",pcbs[i].name,pcbs[i].ArriveTime,pcbs[i].ServiceTime,pcbs[i].StartTime,pcbs[i].FinishTime,pcbs[i].WholeTime,pcbs[i].WeightWholeTime);
}
averageWholeTime=x/n;
averageWeightWhole=y/n;
printf("平均周转时间=%.2f 平均带权周转时间=%.2f\n",averageWholeTime,averageWeightWhole);
fprintf(fp,"平均周转时间=%.2f 平均带权周转时间=%.2f\n",averageWholeTime,averageWeightWhole);
fclose(fp);
return 0;
}
void run_FCFS() //运行未完成的进程
{
int n=count_line("C:\\Users\\12280\\Desktop\\进程.txt");
int size=3*n;
FILE *fp=fopen("C:\\Users\\12280\\Desktop\\res.txt","a");
for(i=0;i<size;i+=3){
time = pcbs[i].ArriveTime>time?pcbs[i].ArriveTime:time;
pcbs[i].StartTime=time;
printf("--->时刻:%d, 正在运行的作业:%d\n",time,pcbs[i].name);
time+=pcbs[i].ServiceTime;
pcbs[i].runFlag=1;
pcbs[i].FinishTime=time;
pcbs[i].WholeTime=pcbs[i].FinishTime-pcbs[i].ArriveTime;
pcbs[i].WeightWholeTime=pcbs[i].WholeTime/pcbs[i].ServiceTime;
x+=pcbs[i].WholeTime;
y+=pcbs[i].WeightWholeTime;
// printf("\n===========================================================================\n");
printf("作业名 到达时间 开始时间 服务时间 完成时间 周转时间 带权周转时间\n");
// printf("---------------------------------------------------------------------------\n");
printf("%4d %6d %10d %10d %8d %10.1f %10.2f\n",pcbs[i].name,pcbs[i].ArriveTime,pcbs[i].StartTime,pcbs[i].ServiceTime,pcbs[i].FinishTime,pcbs[i].WholeTime,pcbs[i].WeightWholeTime);
fprintf(fp,"进程名字=%4d 进程到达时间=%6d 进程开始时间=%10d 进程服务时间=%10d 进程结束时间=%8d 周转时间=%10.1f 带权周转时间=%10.2f\n",pcbs[i].name,pcbs[i].ArriveTime,pcbs[i].StartTime,pcbs[i].ServiceTime,pcbs[i].FinishTime,pcbs[i].WholeTime,pcbs[i].WeightWholeTime);
}
averageWholeTime=x/n;
averageWeightWhole=y/n;
printf("平均周转时间=%.2f 平均带权周转时间=%.2f\n",averageWholeTime,averageWeightWhole);
fprintf(fp,"平均周转时间=%.2f 平均带权周转时间=%.2f\n",averageWholeTime,averageWeightWhole);
fclose(fp);
}
void getInfo() //获得进程信息并创建进程
{
char* path="C:\\Users\\12280\\Desktop\\进程.txt";//读取文件里的信息
int data[100],i;
int n=count_line("C:\\Users\\12280\\Desktop\\进程.txt");
int size=3*n;
FILE *fp=fopen(path,"r");
for(i=0;!feof(fp);i++){
fscanf(fp,"%d",&data[i]);
}
for(i=0;i<size;i+=3)
{
pcbs[i].name=data[i];
pcbs[i].ArriveTime=data[i+1];
pcbs[i].ServiceTime=data[i+2];
pcbs[i].serviceTime1=data[i+2];
}
for(i=0;i<size;i+=3){
pcbs[i].StartTime=0;
pcbs[i].FinishTime=0;
pcbs[i].WholeTime=0;
pcbs[i].WeightWholeTime=0;
pcbs[i].runFlag=0;
pcbs[i].startFlag=0;
}
}
void main()
{
int k;
FILE *fp=fopen("C:\\Users\\12280\\Desktop\\res.txt","a");
printf("选择要进行调度的算法 1:先来先服务算法模拟;2:时间片轮转算法模拟\n");
scanf("%d",&k);
switch (k)
{
case 1:
printf("先来先服务算法模拟\n");
getInfo();
run_FCFS();
main();
break;
case 2:
printf("时间片轮转算法模拟\n");
getInfo();
run_RR();
poutput();
main();
default:
break;
}
}
今天的文章进程调度—时间片轮转和先来先服务分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/63742.html