用C语言实现先来先服务FCFS进程调度算法

**分析:**先来先服务的意思就是哪个进程先到就先进行哪个进程,只与来的先后次序有关,等第一个进程执行完之后才会进程下一个进程的执行。

  1. 只有第一个进程的开始时间是它的到达时间,后边的进程开始时间都是前一个进的完成时间。
  2. 完成时间就等于该进程的开始时间加上服务时间
  3. 周转时间 = 完成时间 - 到达时间
  4. 带权周转时间 = 周转时间 / 服务时间
    在这里插入图片描述

我们可以采用链表把这些进程信息保存起来,当第一个进程(结点)结束后,再进行下一个进程(结点)。我这里采用的是头插方法,结点插入完成后,最后一个进程是当前的头结点,所以要进行链表反转,将链表顺序转回来,这样才能计算正确。

代码如下:
test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"os.h"

int main()
{
	_PCB* pcb;
	InitPcb(&pcb);//初始化函数
	printf("进程名\t到达时间\t服务时间\n");
	Input(&pcb);//插入结点
	OrderServer(_PCB** pcb);//核心算法
	return 0;
}

os.c

void InitPcb(_PCB** pcb)
{
	assert(pcb);
	if (NULL == (*pcb))
		return;
	(*pcb) = NULL;
}

_PCB* BuyNode(_PCB* pcb)
{
	_PCB* newNode = (_PCB*)malloc(sizeof(_PCB));
	if (NULL == newNode)
		return NULL;
	else
	{
		setbuf(stdin, NULL);
		scanf("%c %d %d", &newNode->Name, &newNode->ArriveTime, &newNode->ServerTime);
		newNode->next = NULL;
		return newNode;
	}
}

void PushFront(_PCB** pcb)//头插
{
	_PCB* cur = NULL;
	assert(pcb);
	if (*pcb == NULL)
	{
		(*pcb) = BuyNode(*pcb);
		return;
	}
	else
	{
		cur = BuyNode(*pcb);
		cur->next = (*pcb);
		(*pcb) = cur;
	}
}

void Input(_PCB** pcb)
{
	int i = 0;
	for (i = 0; i < MAX; i++)
	{
		PushFront(pcb);
	}
}

void Print(_PCB** pcb)
{
	_PCB* cur = NULL;
	cur = (*pcb);
	assert(pcb);
	if (NULL == (*pcb))
		return;
	printf("进程名\t到达时间\t服务时间\t开始执行时间\t完成时间\t周转时间\t带权周转时间\n");
	while (cur)
	{
		printf("%c\t%d\t%d\t%d\t%d\t%d\t%f\n", cur->Name, cur->ArriveTime, cur->ServerTime, cur->StartTime, cur->FinishTime, cur->WholeTime, cur->ValueWholeTime);
		cur = cur->next;
	}
}

void Turn(_PCB** pcb)//反转链表
{
	_PCB* cur = (*pcb);
	_PCB* pre = cur->next;
	_PCB* pb = pre->next;
	assert(pcb);
	if (NULL == pcb)
		return;
	cur->next = NULL;
	while (pre && pb)
	{
		pre->next = cur;
		cur = pre;
		pre = pb;
		pb = pb->next;
	}
	pre->next = cur;
	(*pcb) = pre;
}

void OrderServer(_PCB** pcb)
{
	_PCB* cur = NULL;
	_PCB* pre = NULL;//用来记录前一个结点,计算开始执行时间需要用到前一个结点的信息
	Turn(pcb);
	cur = pre = (*pcb);
	assert(pcb);
	int i = 0;//记录当前是第几个进程
	if (NULL == (*pcb))
		return;
	while (cur)
	{
		if (0 == i || 1 == i)//说明是第一个/第二个进程
		{
			if (0 == i)
			{
				cur->StartTime = cur->ArriveTime;
				i++;
			}
			else//是第二个进程,因为第二个进程的pre是头结点,所以不需要移动,单独出来
			{
				cur->StartTime = pre->FinishTime;
				i++;
			}
			cur->FinishTime = cur->ServerTime + cur->StartTime;
			cur->WholeTime = cur->FinishTime - cur->ArriveTime;
			cur->ValueWholeTime = (float)cur->WholeTime / (float)cur->ServerTime;
			cur = cur->next;
		}
		else
		{
			pre = pre->next;
			cur->StartTime = pre->FinishTime;
			cur->FinishTime = cur->ServerTime + cur->StartTime;
			cur->WholeTime = cur->FinishTime - cur->ArriveTime;
			cur->ValueWholeTime = (float)cur->WholeTime / (float)cur->ServerTime;
			cur = cur->next;
			i++;
		}
	}
}

os.h

#ifndef __OS_H__
#define __OS_H__
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#define MAX 4

typedef struct PCB{
	char Name;//进程名
	int ArriveTime;//到达时间
	int ServerTime;//服务时间
	int Time;//时间片
	int Front;//优先级
	int StartTime;//开始执行时间
	int FinishTime;//完成时间
	int WholeTime;//周转时间
	float ValueWholeTime;//带权周转时间
	int Ago;//标记当前结点有没有被访问过
	struct PCB* next;
	int AddTime;//累加时间
	int AtTime;//当前时刻
}_PCB;

void InitPcb(_PCB** pcb);//初始化
_PCB* BuyNode(_PCB* pcb);
void PushFront(_PCB** pcb);//头插
void Input(_PCB** pcb);//输入函数
void Print(_PCB** pcb);//打印
void OrderServer(_PCB** pcb);//先来先服务
void Turn(_PCB** pcb);//将链表翻转过来

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/huaijiu123/article/details/83719613
今日推荐