操作系统-进程调度算法(FCFS,SJF,RR,PSA)-C实现

程序流程

  1. 用户输入进程的数量,确定进程的开始时间,和进程的运行时间,优先数(越大优先权越高)。
  2. 选择调度规则。调度规则有:FCFS,SJF,RR,动态高优先权优先(需要特别设定优先权,并且可动态修改)。
  3. 最后输出进程的调度顺序和每个进程的运行时间,进程名_进程id(运行时间)。如:p1_1(2),p2_2(3),p3_3(4),p5_5(6)形式。

源码如下:
main.cpp

//进程调度模拟
#include<stdio.h>
#include<stdlib.h>
#define MAX_PROCESSES 10
#define MAX_NAME 5
int processes = 0;
#include"pcb_1.h"
pcb pcb_arrs[MAX_PROCESSES]={0};
#include"process_queue.h"
Queue ReadyQue;
#include"schedule_1.h"

//冒泡排序
void bubbleSortByArrive()
{
	pcb tmp;
	for(int i = 0; i < processes-1; i++){
		for(int j = i+1; j < processes; j++){
			if(pcb_arrs[i].pcb_beginning_time > pcb_arrs[j].pcb_beginning_time)
			{
				tmp = pcb_arrs[i];
				pcb_arrs[i] = pcb_arrs[j];
				pcb_arrs[j] = tmp;
			}
		}
	}
}

// 欢迎界面
void welcome()
{
	printf("#########################################################\n");
	printf("	Welcome to Process scheduling simulation\n");
	printf("		   Author : @zsjjsd\n");
	printf("#########################################################\n");
}
//输入进程的数量
void input_processes()
{
	printf("Please input the number of processes(int,max=%d) : ",MAX_PROCESSES);
	scanf("%d",&processes);
	if(processes>MAX_PROCESSES)
	{
		printf("Processes too many!\n");
		exit(0);
	}
	printf("processes : %d\n\n",processes);
}
//初始化进程
void initialize()
{
	char name[MAX_NAME]={0};
	int beignning_time = 0;
	int running_time = 0;
	for(int i = 0; i < processes; ++i)//创建对应数量的进程
	{
		printf("Please input the %d pcb_name(length = 5) : ",i+1);
		scanf("%s",name);
		printf("Please input the %d pcb_beginning_time(int) : ",i+1);
		scanf("%d",&beignning_time);
		printf("Please input the %d pcb_running_time(int) : ",i+1);
		scanf("%d",&running_time);
		pcb_arrs[i] = create_pcb(name,beignning_time,running_time);
	}
}
//输出进程
void output_processes()
{
	for(int j = 0; j < processes; ++j)
	{
		printf("pcb_id=%d,pcb_name=%s,pcb_beginning_time=%d,pcb_running_time=%d,pcb_privileges=%d\n",
			pcb_arrs[j].pcb_id,pcb_arrs[j].pcb_name,pcb_arrs[j].pcb_beginning_time,pcb_arrs[j].pcb_running_time,pcb_arrs[j].pcb_privileges);
	}
}
void chooseSchedule()
{
	char flag = '0';
	printf("Please choose the scheduling algorithm:\n");
	printf("	Scheduling algorithm list:\n");
	printf("		Press 1 for FCFS\n");
	printf("		Press 2 for SJF\n");
	printf("		Press 3 for RR\n");
	printf("		Press 4 for PSA\n");
	printf("Press your choose : ");
	getchar();
	flag = getchar();
	if(flag=='1')
		FCFS();
	else if(flag=='2')
		SJF();
	else if(flag=='3')
		RR();
	else if(flag=='4')
		PSA();
	else
		printf("Please press the correct char!\n");
}
int main(void)
{
	/*
		程序流程:
			用户输入进程的数量,确定进程的开始时间,和进程的运行时间,优先数(越大优先权越高)。
			选择调度规则。调度规则有:FCFS,SJF,RR,动态高优先权优先(需要特别设定优先权,并且可动态修改)。
			最后输出进程的调度顺序和每个进程的运行时间,进程名_进程id(运行时间)。
				如:p1_1(2),p2_2(3),p3_3(4),p5_5(6)形式。
			
	*/
	//---初始化进程
	welcome();
	input_processes();
	initialize();
	bubbleSortByArrive();//按到达时间排序
	output_processes();
	//-------------
	printf("\n");
	//执行进程调度
	init(&ReadyQue);//初始化就绪队列
	chooseSchedule();//选择调度算法
	//-------------
	destroyQue(&ReadyQue);
	return 0;
}

pcb.h(进程控制块数据结构)

#ifndef _PCB_1_H
#define _PCB_1_H
#include<malloc.h>
#include<string.h>

int pcbId=0;
int pcb_ids[MAX_PROCESSES]={0};//存储pcb的所有id,保证每个pcb都是唯一的。创建pcb时加入id到此数组,删除pcb时,也从此删除
//进程控制块
typedef struct PCB{
	int pcb_id;//pcb的id,每个pcb都是唯一的。
	char pcb_name[MAX_NAME];//pcb的名字
	int pcb_beginning_time;//进程的开始时间
	int pcb_running_time;//进程的运行时间
	int pcb_privileges;//进程的优先级,在需要优先级时初始化
}pcb,*ppcb;

//创建进程,即创建进程控制块,并初始化pcb
pcb create_pcb(char * name, int beginning_time, int running_time)
{
	//初始化开始
	pcb tPcb;
	tPcb.pcb_id = pcbId+1;//初始化pcdid
	pcb_ids[pcbId++] = tPcb.pcb_id;//记录创建的pcb
	strcpy(tPcb.pcb_name,name);//初始化name
	//tPcb.pcb_name = name;
	tPcb.pcb_beginning_time = beginning_time;//初始化开始时间
	tPcb.pcb_running_time = running_time;//初始化运行时间
	tPcb.pcb_privileges = 0;//默认没有优先权。特定算法需要,可动态修改
	//初始化完毕
	printf("initialized over!pcb_id=%d,pcb_name=%s,pcb_beginning_time=%d,pcb_running_time=%d,pcb_privileges=%d\n\n",
		tPcb.pcb_id,tPcb.pcb_name,tPcb.pcb_beginning_time,tPcb.pcb_running_time,tPcb.pcb_privileges);
	return tPcb;
}

#endif

queue_1.h(队列数据结构)

#ifndef _PROCESS_QUEUE_H
#define _PROCESS_QUEUE_H

/*
	2022年10月30日22点26分
	完成队列的一些简单功能 
	循环队列关键的算法为:位置取补 
		 (i+1)%length 
*/ 

#define MAX_LENGTH (MAX_PROCESSES+1)

typedef pcb ElementType;

typedef struct Queue
{
	ElementType *pBase;//数组首元素地址 
	int front;//队头 
	int rear;//队尾 
}QUEUE, *pQUEUE; 

void init(pQUEUE pQ)//初始化队列 
{
	pQ->pBase = (ElementType *)malloc(sizeof(ElementType) * MAX_LENGTH);
	if(!pQ->pBase) 
		exit(-1);
	pQ->front = 0; 
	pQ->rear = 0;
}
bool QueueFull(pQUEUE pQ)//判断队列是否为满 
{
	if(pQ->front == (pQ->rear+1) % MAX_LENGTH)
		return true;
	return false;
}
bool QueueEmpty(pQUEUE pQ)//判断队列是否为空 
{
	if(pQ->front == pQ->rear)
		return true;
	return false;
}
bool enQueue(pQUEUE pQ, ElementType val)//入队 
{
	if(QueueFull(pQ))
		return false; 
	pQ->pBase[pQ->rear] = val;
	pQ->rear = (pQ->rear+1) % MAX_LENGTH;
	return true;
}
bool outQueue(pQUEUE pQ, ElementType * e)//出队 
{
	if(QueueEmpty(pQ))
		return false;
	*e = pQ->pBase[pQ->front];
	pQ->front = (pQ->front+1) % MAX_LENGTH;
	return true;
}
/*void traverse(pQUEUE pQ)//遍历队列 
{
	int i = pQ->front;
	while(i != pQ->rear)
	{
		printf("%d ",pQ->pBase[i]);
		i = (i+1) % MAX_LENGTH;
	}
	printf("\n");
}*/
int QueLength(pQUEUE pQ)//队列的长度 
{
	return (pQ->rear - pQ->front + MAX_LENGTH) % MAX_LENGTH;
}
void clearQue(pQUEUE pQ)//清空队列 
{
	pQ->front = pQ->rear = 0;
}
void destroyQue(pQUEUE pQ)//销毁队列 
{
	if(pQ->pBase)
		free(pQ->pBase);
	pQ->pBase = NULL;
	pQ->front = pQ->rear = 0;
}
#endif

schedule.h(进程调度算法)

#ifndef _SCHEDULE_1_H
#define _SCHEDULE_1_H

//输出进程
void outputProcess(ppcb ptemp)
{
	for(int j = 0; j < processes; ++j)
	{
		printf("pcb_id=%d,pcb_name=%s,pcb_beginning_time=%d,pcb_running_time=%d,pcb_privileges=%d\n",
			ptemp[j].pcb_id,ptemp[j].pcb_name,ptemp[j].pcb_beginning_time,ptemp[j].pcb_running_time,ptemp[j].pcb_privileges);
	}
}
void bubbleSortByRunning(ppcb pPcb,int cnt)
{
	pcb tmp;
	for(int i = 0; i < cnt-1; i++){
		for(int j = i+1; j < cnt; j++){
			if(pPcb[i].pcb_running_time > pPcb[j].pcb_running_time)
			{
				tmp = pPcb[i];
				pPcb[i] = pPcb[j];
				pPcb[j] = tmp;
			}
		}
	}
}
void bubbleSortByPrivileges(ppcb pPcb,int cnt)
{
	pcb tmp;
	for(int i = 0; i < cnt-1; i++){
		for(int j = i+1; j < cnt; j++){
			if(pPcb[i].pcb_privileges < pPcb[j].pcb_privileges)
			{
				tmp = pPcb[i];
				pPcb[i] = pPcb[j];
				pPcb[j] = tmp;
			}
		}
	}
}
//先来先服务
void FCFSService()
{
	printf("FCFSService:\n\t");
	int i = 0;
	//将进程放入就绪队列中
	while(true)
	{
		if(i == processes)
			break;
		printf("%s_%d(%d) ",pcb_arrs[i].pcb_name,pcb_arrs[i].pcb_id,pcb_arrs[i].pcb_running_time);//服务
		i++;
	}
	printf("\n\n");
}
void SJForPSACPUService(ppcb arrive_arr,int cnt,int * now)
{
	for(int i = 0; i < cnt; i++)
	{
		printf("%s_%d(%d) ",arrive_arr[i].pcb_name,arrive_arr[i].pcb_id,arrive_arr[i].pcb_running_time);
		*now+=arrive_arr[i].pcb_running_time;
	}
}
void getArrive(ppcb arrive_arr,int *i, int *cnt, int *now)
{
	while(true)
	{
		if(*i == processes)
			break;
		if(pcb_arrs[*i].pcb_beginning_time <= *now)
		{
			arrive_arr[*cnt] = pcb_arrs[*i];
			++*i;
			++*cnt;
		}	
		else
			break;
	}
}
void SJFService()
{
	printf("SJFService:\n\t");
	pcb arrive_arr[MAX_PROCESSES]={0};
	int i = 0;
	int cnt = 0;
	int now = pcb_arrs[0].pcb_beginning_time;
	//将进程按SJF算法排序放入就绪队列中。
	//取出已到达的进程,按运行时间从小到大排序,放入就绪队列中。并且进行服务,
	while(true)
	{
		cnt = 0;
		if(i == processes)
			break;
		//取出已到达的进程,根据时间找。
		getArrive(arrive_arr,&i,&cnt,&now);
		bubbleSortByRunning(arrive_arr,cnt);
		SJForPSACPUService(arrive_arr,cnt,&now);
	}
	printf("\n");
}
void RRCPUService(int *now, int *that, ppcb tmp_arr, int serviceTime)
{
	int i = 0;
	pcb tmp;
	outQueue(&ReadyQue,&tmp);
	serviceTime = tmp.pcb_running_time > serviceTime ? serviceTime : tmp.pcb_running_time;
	printf("%s_%d(%d) ",tmp.pcb_name,tmp.pcb_id,serviceTime);
	*now += serviceTime;
	tmp.pcb_running_time -= serviceTime;
	//在服务的进程插入队尾之前,已到达的进程要先插入。
	for(i = *that; i < processes; i++)
	{
		if(tmp_arr[i].pcb_beginning_time <= *now)
			enQueue(&ReadyQue,tmp_arr[i]);
		else
			break;
	}
	*that = i;
	if(tmp.pcb_running_time > 0)
		enQueue(&ReadyQue,tmp);
}
void RRService(int slot)
{
	printf("RRService:\n\t");
	int now = 0;
	pcb tmp_arr[MAX_PROCESSES] = {0};
	for(int i = 0; i < processes; i++)
	{
		tmp_arr[i] = pcb_arrs[i];
	}
	enQueue(&ReadyQue,pcb_arrs[0]);
	int that = 1;
	while(!QueueEmpty(&ReadyQue))
		RRCPUService(&now,&that,tmp_arr,slot);
	printf("\n");
}
void setPrivileges(ppcb temp,int cnt)
{
	for(int i = 0; i < cnt; i++)
	{
		printf("\tPlease input %s_%d privileges : ",temp[i].pcb_name,temp[i].pcb_id);
		scanf("%d",&temp[i].pcb_privileges);
	}
}
void PSAService()
{
	printf("PSAService:\n");
	int i = 0;
	int cnt = 0;
	int now = 0;
	pcb temp[MAX_PROCESSES] = {0};
	while(true)
	{
		cnt = 0;
		if(i == processes)
			break;
		getArrive(temp,&i,&cnt,&now);
		setPrivileges(temp,cnt);

		bubbleSortByPrivileges(temp,cnt);
		printf("\t\t");
		SJForPSACPUService(temp,cnt,&now);
		printf("\n");
	}
}
/*
	先来先服务算法,先将进程按到达时间放入队列中,可以先将进程按到达时间排序,然后由小到大放入队列中。
	再从队列中取出进程进行服务。,最后输出服务进程和时间。
*/
void FCFS()
{
	printf("FCFS\n");
	//开始服务并输出服务信息
	FCFSService();
}
void SJF()
{
	printf("SJF\n");
	SJFService();
}
void RR()
{
	int slot = 2;//时间片
	printf("RR\n");
	RRService(slot);
}
void PSA()
{
	printf("PSA\n");
	PSAService();
}

#endif
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值