主要参考链接:
代码绝大多数都是从网上拷下来再自己改了一点。本来想附上参考链接,但时间有点久,找不到主要参考的那个连接。
[声明]本文为转载是因为代码大多数都是网上copy的,然后自己也只是微调加实现过,个人认为不可以当原创。代码全部都贴上来了,txt文档的格式也贴了,也实现过,如果期间遇到困难,希望你们再去找其他的资料,问我的话我未必能答上来。
操作系统系列文章:
主要的数据结构
struct PCB
{
char name[10]; //进程名字
int arrivetime; //到达时间
int servicetime; //服务时间
int finishtime; //完成时刻
int sc; //sign completion标志是否完成
int st1; //剩余服务时间
int rtime;//周转时间
double drtime;
}*p;
PCB process[N];
static int n;//进程数
static int T;//轮转时间片
用到的函数
void input_fcfs(PCB *p);//将存在文档的数据录入到程序中
void input_rr(PCB *p);
void display_fcfs(PCB *p);
void display_rr(PCB *p);
void fcfs(PCB *process,int n);
void rr(PCB *process,int n);
核心算法
先来先服务
void fcfs(PCB *process,int n){
int i,j;
display_fcfs(process);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++) //按照各进程到达时间升序,对进程排序 注意:稳定的排序 冒泡
{
if(process[j].arrivetime<process[i].arrivetime)
{
process[0]=process[j]; //0作为转换站
process[j]=process[i];
process[i]=process[0];
}
}
//fcfs
int time=process[1].arrivetime; //当前时间的初值
int sum=0; //记录完成的进程数
printf("\n第几次调度进程 运行进程名 开始运行时间 服务时间 完成时间 周转时间 带权周转时间\n");
int z=1; //记录第几次调度进程
for(i=1;i<=n;i++){
if(process[i].arrivetime>time)time=process[i].arrivetime;
time=time+process[i].servicetime;
process[i].rtime=time-process[i].arrivetime;
process[i].drtime=(double)process[i].rtime/process[i].servicetime;
printf("%8d%12s%15d%11d%9d%9d%14.5f\n",z++,process[i].name,time-process[i].servicetime,process[i].servicetime,time,process[i].rtime,process[i].drtime);
}
}
时间片轮转
void rr(PCB *process,int n)
{
int i,j;
display_rr(process);
for(i=0;i<=n;i++)
for(j=i+1;j<=n;j++) //按照各进程到达时间升序,对进程排序 注意:稳定的排序 冒泡
{
if(process[j].arrivetime<process[i].arrivetime)
{
process[0]=process[j]; //0作为转换站
process[j]=process[i];
process[i]=process[0];
}
}
int time=process[1].arrivetime; //当前时间的初值
int flag=1;
int sum=0; //记录完成的进程数
printf("\n第几次调度进程 运行进程名 开始运行时间 运行时间 剩余服务时间 结束时间 完成时间 周转时间 带权周转时间\n");
int z=1; //记录第几次调度进程
int aa=1; //数组abc的储存变量
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].arrivetime)//未完成的进程但是还需服务的时间少于等于一个时间片
{
flag=1;
time=time+process[i].st1;
process[i].sc=1;
process[i].finishtime=time;
process[i].rtime=time-process[i].arrivetime;
process[i].drtime=(double)process[i].rtime/process[i].servicetime;
printf("%8d%12s%15d%11d%11d%11d%9d%9d%14.5f\n",z++,process[i].name,time-process[i].st1,process[i].st1,0,time,time,process[i].rtime,process[i].drtime);
process[i].st1=0;
}
else if(process[i].st1>T&&time>=process[i].arrivetime)//未完成的进程但其还需服务时间至少大于一个时间片
{
flag=1;
time=time+T;
process[i].st1-=T;
printf("%8d%12s%15d%11d%11d%11d\n",z++,process[i].name,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].arrivetime;break;}
}
}
}
主函数(个人感觉指针p有点多余,可以直接用process。)
int main()
{
int a;
printf("进程调度算法:1.FCFS 2.RR 3.quit\n");
scanf("%d",&a);
while(a!=3){
switch(a){
case 1:
printf("\t\t先来先服务调度算法\n");
input_fcfs(process);
p=process;
fcfs(p,n);
break;
case 2:
printf("\t\t时间片轮转调度算法\n");
input_rr(process);
p=process;
rr(p,n);
break;
case 3:
printf("end.\n");
default:
break;
}
// system("cls");
printf("\n进程调度算法:1.fcfs 2.rr 3.quit\n");
scanf("%d",&a);
}
return 0;
}
测试数据的输入
源代码
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#define N 50
struct PCB
{
char name[10]; //进程名字
int arrivetime; //到达时间
int servicetime; //服务时间
int finishtime; //完成时刻
int sc; //sign completion标志是否完成
int st1; //剩余服务时间
int rtime;//周转时间
double drtime;
}*p;
PCB process[N];
static int n;//进程数
static int T;//轮转时间片
void input_fcfs(PCB *p);//将存在文档的数据录入到程序中
void input_rr(PCB *p);
void display_fcfs(PCB *p);
void display_rr(PCB *p);
void fcfs(PCB *process,int n);
void rr(PCB *process,int n);
void input_fcfs(PCB *p){
int i;
FILE *fp;
fp=fopen("fcfs输入数据.txt","r");
if(fp==NULL){
exit(EXIT_FAILURE);
}
fscanf(fp,"%d",&n);
for(i=1;i<=n;i++){
fscanf(fp,"%s %d %d",&p[i].name,&p[i].arrivetime,&p[i].servicetime);
p[i].sc=0;
p[i].st1=p[i].servicetime;
}
}
void input_rr(PCB *p){
int i;
FILE *fp;
fp=fopen("rr输入数据.txt","r");
if(fp==NULL){
exit(EXIT_FAILURE);
}
fscanf(fp,"%d",&T);
fscanf(fp,"%d",&n);
for(i=1;i<=n;i++){
fscanf(fp,"%s %d %d",&p[i].name,&p[i].arrivetime,&p[i].servicetime);
p[i].sc=0;
p[i].st1=p[i].servicetime;
}
}
void display_fcfs(PCB *p){
printf("输入的数据:\n");
printf("进程数:%d\n",n);
printf("进程名 到达时间 服务时间\n");
for(int i=1;i<=n;i++){
printf(" %s %2d %2d\n",p[i].name,p[i].arrivetime,p[i].servicetime);
}
}
void display_rr(PCB *p){
printf("输入的数据:\n");
printf("时间片:%d\n",T);
printf("进程数:%d\n",n);
printf("进程名 到达时间 服务时间\n");
for(int i=1;i<=n;i++){
printf(" %s %2d %2d\n",p[i].name,p[i].arrivetime,p[i].servicetime);
}
}
void fcfs(PCB *process,int n){
int i,j;
display_fcfs(process);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++) //按照各进程到达时间升序,对进程排序 注意:稳定的排序 冒泡
{
if(process[j].arrivetime<process[i].arrivetime)
{
process[0]=process[j]; //0作为转换站
process[j]=process[i];
process[i]=process[0];
}
}
//fcfs
int time=process[1].arrivetime; //当前时间的初值
int sum=0; //记录完成的进程数
printf("\n第几次调度进程 运行进程名 开始运行时间 服务时间 完成时间 周转时间 带权周转时间\n");
int z=1; //记录第几次调度进程
for(i=1;i<=n;i++){
if(process[i].arrivetime>time)time=process[i].arrivetime;
time=time+process[i].servicetime;
process[i].rtime=time-process[i].arrivetime;
process[i].drtime=(double)process[i].rtime/process[i].servicetime;
printf("%8d%12s%15d%11d%9d%9d%14.5f\n",z++,process[i].name,time-process[i].servicetime,process[i].servicetime,time,process[i].rtime,process[i].drtime);
}
}
void rr(PCB *process,int n)
{
int i,j;
display_rr(process);
for(i=0;i<=n;i++)
for(j=i+1;j<=n;j++) //按照各进程到达时间升序,对进程排序 注意:稳定的排序 冒泡
{
if(process[j].arrivetime<process[i].arrivetime)
{
process[0]=process[j]; //0作为转换站
process[j]=process[i];
process[i]=process[0];
}
}
int time=process[1].arrivetime; //当前时间的初值
int flag=1;
int sum=0; //记录完成的进程数
printf("\n第几次调度进程 运行进程名 开始运行时间 运行时间 剩余服务时间 结束时间 完成时间 周转时间 带权周转时间\n");
int z=1; //记录第几次调度进程
int aa=1; //数组abc的储存变量
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].arrivetime)//未完成的进程但是还需服务的时间少于等于一个时间片
{
flag=1;
time=time+process[i].st1;
process[i].sc=1;
process[i].finishtime=time;
process[i].rtime=time-process[i].arrivetime;
process[i].drtime=(double)process[i].rtime/process[i].servicetime;
printf("%8d%12s%15d%11d%11d%11d%9d%9d%14.5f\n",z++,process[i].name,time-process[i].st1,process[i].st1,0,time,time,process[i].rtime,process[i].drtime);
process[i].st1=0;
}
else if(process[i].st1>T&&time>=process[i].arrivetime)//未完成的进程但其还需服务时间至少大于一个时间片
{
flag=1;
time=time+T;
process[i].st1-=T;
printf("%8d%12s%15d%11d%11d%11d\n",z++,process[i].name,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].arrivetime;break;}
}
}
}
int main()
{
int a;
printf("进程调度算法:1.FCFS 2.RR 3.quit\n");
scanf("%d",&a);
while(a!=3){
switch(a){
case 1:
printf("\t\t先来先服务调度算法\n");
input_fcfs(process);
p=process;
fcfs(p,n);
break;
case 2:
printf("\t\t时间片轮转调度算法\n");
input_rr(process);
p=process;
rr(p,n);
break;
case 3:
printf("end.\n");
default:
break;
}
// system("cls");
printf("\n进程调度算法:1.fcfs 2.rr 3.quit\n");
scanf("%d",&a);
}
return 0;
}
实验截图
先来先服务的实验结果:
时间片轮转的实验结果
一个粗略的小结:相同的三个进程块,FCFS的平均带权周转时间为1/3(1+5+1)=2.33,RR的平均带权周转时间为1/3(4+1.2+1)=2.07。因此时间片轮转调度算法在一定条件下它的性能好过先来先服务算法。