纯c语言写先来先服务和时间片轮转这两个进程调度算法

主要参考链接:

代码绝大多数都是从网上拷下来再自己改了一点。本来想附上参考链接,但时间有点久,找不到主要参考的那个连接。

[声明]本文为转载是因为代码大多数都是网上copy的,然后自己也只是微调加实现过,个人认为不可以当原创。代码全部都贴上来了,txt文档的格式也贴了,也实现过,如果期间遇到困难,希望你们再去找其他的资料,问我的话我未必能答上来。

 

操作系统系列文章:

1.进程调度算法FCFS和RR

2.作业调度算法SJF和HRRN

3.动态分区分配算法的FirstFit和BestFit

4.银行家算法

 

主要的数据结构

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。因此时间片轮转调度算法在一定条件下它的性能好过先来先服务算法。

  • 0
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值