C++实现进程调度算法(FCFS&RR&优先级调度&SJF)

一、文章概述

        文章根据已给条件(实验课老师给的)对进程调度算法进行分析,应用范围有限,但可以初步了解进程调度算法,由于本人学识浅薄,文章中难免有不足和错误之处,恳请读者批评指正。

实验内容如下:

二、进程调度算法

首先定义一下进程的控制信息:

#define max 50
struct PCB
{

	int name;
	int arrivetime; //到达时间
	int servicetime; //服务时间
	int finishtime; //完成结束时间
	int turntime; //周转时间
	int weight_turntime; //带权周转时间
	int sign; //标志进程是否完成
	int remain_time; //剩余时间
	int priority;  //优先级

}pcb[max];//进程控制块数组,其中每个元素代表一个进程,并包含诸如到达时间(arrivetime)、剩余时间(remain_time)、完成时间(finishtime)等属性。注:下标从1开始


int main() {
	int n;
	printf("input the number of process\n");
	scanf("%d", &n);
	init(n);//初始化进程
	creat(n);//创建进程
	layout(n);//选择相应的调度算法 
	return 0;

}

void init(int n)  //初始化
{
	int i;
	for (i = 0; i <= n; i++)//元素均初始化为0
	{
		pcb[i].arrivetime = 0;
		pcb[i].servicetime = 0;
		pcb[i].starttime = 0;
		pcb[i].finishtime = 0;
		pcb[i].turntime = 0;
		pcb[i].weight_turntime = 0;
		pcb[i].remain_time = 0;
		pcb[i].sign = 0;
		pcb[i].priority = 0;
	}
}

void creat(int n) //创建PCB
{
	int i;
	for (i = 1; i <= n; i++)//输入我们提供的进程信息
	{
		printf("\n%d:\n input the information of process\n 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 layout(int n)
{
	int ch = 0;
	printf("\t\t************schedule algorithm************\n");
	printf("\t\t1.FSFS\n");
	printf("\t\t2.timesegment\n");
	printf("\t\t3.priority\n");
	printf("\t\t4.SJF\n");
	printf(" choose the algorithm:\n");
	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;
	case 4:
		SJF(n);
		break;
	default:printf("enter error data!\n");
		//P:int类型的变量,case后面不要加''
	}
}

(一)先来先服务

先来先服务,也就是谁先来谁就先执行,即arrivetime越小执行的越早

预期结果:

代码实现:

void FCFS(int n) //先来先服务
{
	int starttime;//系统开始工作的时间
	printf("input the start time:\n");
	scanf("%d", &starttime);
    //我们虽然没有在pcd[0]中放我们的进程,但我们可以把他想象成一个需要服务时间为0的进程,有助于后面进程状态的计算
	if (starttime >= pcb[0].arrivetime)//这种情况也就是,进程到达了,但系统还没开始工作
	{    //所以完成时间是,系统开始工作的时间+进程需要接受服务的时间
		pcb[0].finishtime = pcb[0].servicetime + starttime;
	}
	else
	{    //这种就是正常情况了
		pcb[0].finishtime = pcb[0].arrivetime + pcb[0].servicetime;
	}

	int i;
	for (i = 1; i <= n; i++)
	{
		if (pcb[i - 1].finishtime > pcb[i].arrivetime) {
        //这种情况是,虽然第i个进程已到达,但它的上一个进程还未结束,所以要等到上一进程结束它才能开始执行
			pcb[i].finishtime = pcb[i - 1].finishtime + pcb[i].servicetime;
		}
		else {
            
			pcb[i].finishtime = pcb[i].arrivetime + pcb[i].servicetime;
		}
		pcb[i].turntime = pcb[i].finishtime - pcb[i].arrivetime;//周转时间
		pcb[i].weight_turntime = pcb[i].turntime / pcb[i].servicetime;//带权周转时间=周转时间/服务时间
	}
}




void print_FCFS(int n)//输入结果
{
	
	printf("process ID  arrivetime servicetime finishtime turntime , averageturntime  .\n");
	int i;
	for (i = 1; i <= n; i++)
	{
		printf("%d  ,%d  ,%d  ,%d  ,%d  ,%d  ", pcb[i].name, pcb[i].arrivetime, pcb[i].servicetime, pcb[i].finishtime, pcb[i].turntime, pcb[i].weight_turntime);
		printf("\n");
	}

}

使starttime = 0, 执行结果(与预期相符):

(二)时间片轮转调度算法

初始时按FCFS的方式排队,每个进程执行完一个时间片后,就移到队尾,等待下一次调度:

代码实现:

void time_segment(int n) //时间片轮转调度
{
	int i, j;
	int T;   //时间片
	int flag = 1;   //就绪队列中是否还有进程
	int time=pcb[1].arrivetime;   //记录当前的时间
	int sum = 0;   //已经完成的进程数

	//时间片轮转调度算法,初始时按FCFS的方式排队,所以按各进程的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("input the slice time:\n");
	scanf("%d", &T);//输入时间片大小

	while (sum < n)//使用while循环遍历所有进程,直到所有进程都已完成。
	{
		flag = 0;   //当前就绪队列中没有进程
		int i;
		for (i = 1; i <= n; i++)
		{
			if (pcb[i].sign == 1) {
				continue; //如果进程已完成(`sign==1`),则跳过该进程
			}else
			{
				//没有完成的进程需要的时间大于一个时间片
				if (pcb[i].remain_time > T)
				{
					flag = 1;//将进程放入队列
					time = time + T;//执行完一个时间片后,当前时间+T
					pcb[i].remain_time = pcb[i].remain_time - T;
				}else if (pcb[i].remain_time <= T)//没有完成的进程需要的时间小于或等于一个时间片
				{
					flag = 1;  //加入就绪队列
					time = time + pcb[i].remain_time;//time改为完成该进程后的时间
					pcb[i].finishtime = time;
					pcb[i].sign = 1;//将该进程的状态修改为“已完成”
					pcb[i].remain_time = 0;
				}

				if (pcb[i].sign == 1) sum++;//如果完成了进程pcd[i],则将已完成进程数加1
			}

		}


		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;
	printf("\n processID servicetime finishtime\n");  //进程名   服务时间   完成时间
	for (i = 1; i <= n; i++)
	{
		printf("%6d%10d%10d", pcb[i].name, pcb[i].servicetime, pcb[i].finishtime);
		printf("\n");
	}
}

执行结果:

(三)优先级调度算法(非抢占)

预期结果:

代码实现:

void Priority(int n)
{
	int i, j;
	int time = pcb[1].arrivetime;
	//按各进程按arrivetime进行升序排列,最早到达的进程会直接占用CPU,不需要比较优先级
	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("\n processID servicetime priority finishtime \n");//进程名   服务时间   优先级  完成时间

	//第一个到达的进程执行
	if(i=1){//将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("\n");
	}
	

	//剩余进程按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("\n");
	}

}

执行结果:

(四)短作业优先调度算法(非抢占)

看了(三)中的优先级调度算法后,这个就简单了,就是把servicetime(服务时间),作为优先级

预期结果:

代码实现:

void SJF(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("\n processID servicetime priority finishtime \n");//进程名   服务时间   优先级  完成时间
	//按各进程的arrivetime进行升序排列,最早到达的进程会直接占用CPU,不需要比较优先级
	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("\n");
		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;
		printf("%6d%10d%10d%10d", pcb[i].name, pcb[i].servicetime, pcb[i].priority, pcb[i].finishtime);
		printf("\n");
	}

}

执行结果:

三、所有代码

#include<stdio.h>
#include<malloc.h>


#define max 50
struct PCB
{

	int name;
	int arrivetime; //到达时间
	int servicetime; //服务时间
	int starttime; //开始时间
	int finishtime; //完成结束时间
	int turntime; //周转时间
	int weight_turntime; //带权周转时间
	int sign; //标志进程是否完成
	int remain_time; //剩余时间
	int priority;  //优先级

}pcb[max];

void init(int n);
void creat(int n);
void layout(int n);
void FCFS(int n);
void print_FCFS(int n);
void Priority(int n);
void SJF(int n);
void time_segment(int n);
void print_time(int n);
int main() {
	int n;
	printf("input the number of process\n");
	scanf("%d", &n);
	init(n);
	creat(n);
	layout(n);
	return 0;

}

void init(int n)  //初始化
{
	int i;
	for (i = 0; i <= n; i++)//元素均初始化为0
	{
		pcb[i].arrivetime = 0;
		pcb[i].servicetime = 0;
		pcb[i].starttime = 0;
		pcb[i].finishtime = 0;
		pcb[i].turntime = 0;
		pcb[i].weight_turntime = 0;
		pcb[i].remain_time = 0;
		pcb[i].sign = 0;
		pcb[i].priority = 0;
	}
}

void creat(int n) //创建PCB
{
	int i;
	for (i = 1; i <= n; i++)//输入我们提供的进程信息
	{
		printf("\n%d:\n input the information of process\n 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 layout(int n)
{
	int ch = 0;
	printf("\t\t************schedule algorithm************\n");
	printf("\t\t1.FSFS\n");
	printf("\t\t2.timesegment\n");
	printf("\t\t3.priority\n");
	printf("\t\t4.SJF\n");
	printf(" choose the algorithm:\n");
	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;
	case 4:
		SJF(n);
		break;
	default:printf("enter error data!\n");
		//P:int类型的变量,case后面不要加''
	}
}



void SJF(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("\n processID servicetime priority finishtime \n");//进程名   服务时间   优先级  完成时间
	//按各进程的arrivetime进行升序排列,最早到达的进程会直接占用CPU,不需要比较优先级
	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("\n");
		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;
		printf("%6d%10d%10d%10d", pcb[i].name, pcb[i].servicetime, pcb[i].priority, pcb[i].finishtime);
		printf("\n");
	}

}

void FCFS(int n) //先来先服务
{
	int starttime;//系统开始工作的时间
	printf("input the start time:\n");
	scanf("%d", &starttime);
    //我们虽然没有在pcd[0]中放我们的进程,但我们可以把他想象成一个需要服务时间为0的进程,有助于后面进程状态的计算
	if (starttime >= pcb[0].arrivetime)//这种情况也就是,进程到达了,但系统还没开始工作
	{    //所以完成时间是,系统开始工作的时间+进程需要接受服务的时间
		pcb[0].finishtime = pcb[0].servicetime + starttime;
	}
	else
	{    //这种就是正常情况了
		pcb[0].finishtime = pcb[0].arrivetime + pcb[0].servicetime;
	}

	int i;
	for (i = 1; i <= n; i++)
	{
		if (pcb[i - 1].finishtime > pcb[i].arrivetime) {
        //这种情况是,虽然第i个进程已到达,但它的上一个进程还未结束,所以要等到上一进程结束它才能开始执行
			pcb[i].finishtime = pcb[i - 1].finishtime + pcb[i].servicetime;
		}
		else {
            
			pcb[i].finishtime = pcb[i].arrivetime + pcb[i].servicetime;
		}
		pcb[i].turntime = pcb[i].finishtime - pcb[i].arrivetime;//周转时间
		pcb[i].weight_turntime = pcb[i].turntime / pcb[i].servicetime;//带权周转时间=周转时间/服务时间
	}
}




void print_FCFS(int n)//输入结果
{
	
	printf("process ID  arrivetime servicetime finishtime turntime , averageturntime  .\n");
	int i;
	for (i = 1; i <= n; i++)
	{
		printf("%d  ,%d  ,%d  ,%d  ,%d  ,%d  ", pcb[i].name, pcb[i].arrivetime, pcb[i].servicetime, pcb[i].finishtime, pcb[i].turntime, pcb[i].weight_turntime);
		printf("\n");
	}

}


void Priority(int n)
{
	int i, j;
	int time = pcb[1].arrivetime;
	//按各进程按arrivetime进行升序排列,最早到达的进程会直接占用CPU,不需要比较优先级
	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("\n processID servicetime priority finishtime \n");//进程名   服务时间   优先级  完成时间

	//第一个到达的进程执行
	if(i=1){//将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("\n");
	}
	

	//剩余进程按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("\n");
	}

}

void time_segment(int n) //时间片轮转调度
{
	int i, j;
	int T;   //时间片
	int flag = 1;   //就绪队列中是否还有进程
	int time=pcb[0].arrivetime;   //记录当前的时间
	int sum = 0;   //已经完成的进程数

	//时间片轮转调度算法,初始时按FCFS的方式排队,所以按各进程的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("input the slice time:\n");
	scanf("%d", &T);//输入时间片大小

	while (sum < n)//使用while循环遍历所有进程,直到所有进程都已完成。
	{
		flag = 0;   //当前就绪队列中没有进程
		int i;
		for (i = 1; i <= n; i++)
		{
			if (pcb[i].sign == 1) {
				continue; //如果进程已完成(`sign==1`),则跳过该进程
			}else
			{
				//没有完成的进程需要的时间大于一个时间片
				if (pcb[i].remain_time > T)
				{
					flag = 1;//将进程放入队列
					time = time + T;//执行完一个时间片后,当前时间+T
					pcb[i].remain_time = pcb[i].remain_time - T;
				}else if (pcb[i].remain_time <= T)//没有完成的进程需要的时间小于或等于一个时间片
				{
					flag = 1;  //加入就绪队列
					time = time + pcb[i].remain_time;//time改为完成该进程后的时间
					pcb[i].finishtime = time;
					pcb[i].sign = 1;//将该进程的状态修改为“已完成”
					pcb[i].remain_time = 0;
				}

				if (pcb[i].sign == 1) sum++;//如果完成了进程pcd[i],则将已完成进程数加1
			}

		}


		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;
	printf("\n processID servicetime finishtime\n");  //进程名   服务时间   完成时间
	for (i = 1; i <= n; i++)
	{
		printf("%6d%10d%10d", pcb[i].name, pcb[i].servicetime, pcb[i].finishtime);
		printf("\n");
	}
}

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值