【操作系统】使用C/C++实现进程调度算法

使用C/C++实现进程调度算法

1 先来先服务调度算法
2 优先级调度算法
3 短作业(或进程)优先调度算法
4 响应比高优先调度算法

测试数据:

id reachtime dotime privilege
1 70 20 1
2 80 10 3
3 85 20 4
4 90 5 2

代码:

#define _CRT_SECURE_NO_WARNINGS   //解决VS报错
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
#include<time.h>
#include<memory.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#define getpch(type) (type*)malloc(sizeof(type))
#define inf 0x3f3f3f
using namespace std;

//定义作业信息结构
typedef struct node {
	int number;         //作业号
	int reach_time;     //作业抵达时间
	int need_time;      //作业的执行时间
	int privilege;	    //作业优先权
	float excellent;    //响应比
	int start_time;     //作业开始时间
	int wait_time;      //等待时间
	int tr_time;        //周转时间
	double wtr_time;    //带权周转时间
	int run_time;       //作业累计已执行时间
	bool visited;		//作业是否被访问过
	int finish_time; //作业完成时间
	bool reached; //作业是否抵达
}job;

//停顿几秒
void _sleep(int n) {
	clock_t goal;
	goal = (clock_t)n * CLOCKS_PER_SEC + clock();
	while (goal > clock());
}

//按任意键继续
char _keygo() {
	char c;
	printf("Press any key to continue...\n");
	c = getchar();
	return c;
}

//数据设置区域

const int MAX_NUM = 100;//最大作业数量
const int MAX_LINE = 1024;//一行的size
int num = 0;//实际作业数量
job jobs[MAX_NUM];//作业
//就绪队列
int ready[MAX_NUM];
//记录排序使用哪个数值作为排序对象
int order[MAX_NUM];
void initial_jobs() { //初始化所有作业信息
	for (int i = 0; i < MAX_NUM; i++)
	{
		jobs[i].excellent = 0;
		jobs[i].need_time = 0;
		jobs[i].number = 0;
		jobs[i].privilege = 0;
		jobs[i].reach_time = 0;
		jobs[i].run_time = 0;
		jobs[i].start_time = 0;
		jobs[i].tr_time = 0;
		jobs[i].visited = false;
		jobs[i].wait_time = 0;
		jobs[i].wtr_time = 0;
		jobs[i].finish_time = 0;
		jobs[i].reached = false;
	}
}
void read_Jobdata() { //读取数据文件
	FILE* fp;
	fp = fopen("./test.txt", "r");
	if (fp == NULL) {  //如果文件不存在,则退出
		printf("fail to open the file!\n");
		exit(0);
	}
	char buffer[100];
	printf("start reading...\n");
	fgets(buffer, MAX_LINE, fp);
	cout << buffer;
	num = 0;
	num++;
	while (!feof(fp)) {
		fscanf(fp, "%d%d%d%d", &jobs[num].number, &jobs[num].reach_time, &jobs[num].need_time, &jobs[num].privilege);
		//cout<<jobs[num].number<<" "<<jobs[num].reach_time<<" "<<jobs[num].need_time<<" "<<jobs[num].privilege<<endl;
		num++;
	}
	num--;
	printf("read data success!\n");
	printf("The number of jobs is: %d\n", num);
	printf("%s\n", buffer);
	for (int j = 1; j <= num; j++)
	{
		printf("%d\t%d\t\t%d\t\t%d\n", jobs[j].number, jobs[j].reach_time, jobs[j].need_time, jobs[j].privilege);
	}
	fclose(fp);
}
void initial_jobs_again()
{
	for (int i = 1; i <= num; i++) {
		jobs[i].finish_time = 0;
		jobs[i].excellent = 0;
		jobs[i].tr_time = 0;
		jobs[i].wtr_time = 0;
		jobs[i].wait_time = 0;
		jobs[i].visited = false;
	}
}

//调度函数

//先来先服务算法
void FCFS() {
	int i, j, temp;
	double sum1 = 0; //总的等待时间
	double sum2 = 0; //总的周转时间
	double sum3 = 0; //总的带权周转时间
	for (i = 1; i <= num; i++) {
		order[i] = jobs[i].reach_time;
		ready[i] = i;
	}
	//冒泡排序
	for (i = 1; i <= num; i++) {//按照到达时间大小排序
		for (j = 1; j <= num - i; j++) {
			if (order[j] > order[j + 1]) {
				temp = order[j];
				order[j] = order[j + 1];
				order[j + 1] = temp;
				temp = ready[j];
				ready[j] = ready[j + 1];
				ready[j + 1] = temp;
			}
		}
	}
	for (i = 1; i <= num; i++) {
		printf("%dth work", ready[i]);
		printf("arrival time --%d,service hours--%d\n",
			jobs[ready[i]].reach_time,
			jobs[ready[i]].need_time);
		printf("This job is running...........\n");
		_sleep(1);
		printf("Finished running\n");
		if (i == 1) {
			jobs[ready[i]].finish_time = jobs[ready[i]].reach_time + jobs[ready[i]].need_time;
			jobs[ready[i]].wait_time = 0;
		}
		else {
			if (jobs[ready[i - 1]].finish_time > jobs[ready[i]].reach_time) {  //如果上一个作业的完成时间大于下一个作业的到达时间,则下一个作业的开始时间从上一个的完成时间开始
				jobs[ready[i]].finish_time = jobs[ready[i - 1]].finish_time + jobs[ready[i]].need_time;
				jobs[ready[i]].wait_time = jobs[ready[i - 1]].finish_time - jobs[ready[i]].reach_time;
			}
			else {
				jobs[ready[i]].finish_time = jobs[ready[i]].need_time + jobs[ready[i]].reach_time;
				jobs[ready[i]].wait_time = 0;
			}
		}
		jobs[ready[i]].tr_time = jobs[ready[i]].finish_time - jobs[ready[i]].reach_time;
		jobs[ready[i]].wtr_time = double(jobs[ready[i]].tr_time) / jobs[ready[i]].need_time;
		printf("waiting time: %d Turnaround time: %d Weighted turnaround time: %0.2f\n", jobs[ready[i]].wait_time, jobs[ready[i]].tr_time, jobs[ready[i]].wtr_time);
		sum1 += jobs[ready[i]].wait_time;
		sum2 += jobs[ready[i]].tr_time;
		sum3 += jobs[ready[i]].wtr_time;
	}
	printf("--------All jobs are scheduled------\n");
	printf("Average waiting time: %.2f Average turnaround time: %.2f Average weighted turnaround time: %.2f", sum1 / num, sum2 / num, sum3 / num);
	initial_jobs_again();
}
int findNextSJF(job j[MAX_NUM], int length, int time) {
	// p是已经到达且拥有最短运行时间的进程的下标
	// q是没有到达的进程中拥有最早到达时间的进程的下标
	int i, p, q;
	int minNeedTime, minReachTime, minTime;
	p = q = -1; minTime = minNeedTime = minReachTime = inf;
	for (i = 1; i <= length; i++) {
		if (!j[i].visited) {
			// 第一情况
			if (j[i].reach_time <= time && j[i].need_time <= minNeedTime)
			{
				p = i; minNeedTime = j[i].need_time;
			}
			// 第二种情况
			else if (j[i].reach_time > time && j[i].reach_time <= minReachTime) {
				if (j[i].need_time < minTime)
				{
					q = i; minReachTime = j[i].reach_time; minTime = j[i].need_time;
				}
			}
		}
	}
	// p为-1时,代表在lastTime时刻还没进程到达,此时选择下一个最早到达的进程q
	if (p != -1) return p;
	return q;
}

//短作业优先算法
void SJF() {
	int i, j;
	double sum1 = 0; //总的等待时间
	double sum2 = 0; //总的周转时间
	double sum3 = 0; //总的带权周转时间
	int finish = inf; //当前完成时间
	for (i = 1; i <= num; i++) {
		finish = min(finish, jobs[i].reach_time);
	}
	printf("Short job priority algorithm: \n");
	for (i = 1; i <= num; i++) {
		int index = findNextSJF(jobs, num, finish);
		printf("%dth work", index);
		printf("Arrival time --%d,service hours--%d\n",
			jobs[index].reach_time,
			jobs[index].need_time);
		printf("This job is running...........\n");
		_sleep(1);
		printf("Finished running\n");
		if (jobs[index].reach_time <= finish) {
			jobs[index].wait_time = finish - jobs[index].reach_time;
			jobs[index].start_time = finish;
		}
		else {
			jobs[index].start_time = jobs[index].reach_time;
			jobs[index].wait_time = 0;
		}
		jobs[index].finish_time = jobs[index].start_time + jobs[index].need_time;
		jobs[index].tr_time = jobs[index].finish_time - jobs[index].reach_time;
		jobs[index].wtr_time = (double)jobs[index].tr_time / jobs[index].need_time;
		jobs[index].visited = true;
		sum1 += jobs[index].wait_time;
		sum2 += jobs[index].tr_time;
		sum3 += jobs[index].wtr_time;
		finish = jobs[index].finish_time;
		printf("waiting time: %d Turnaround time: %d Weighted turnaround time: %0.2f\n", jobs[index].wait_time, jobs[index].tr_time, jobs[index].wtr_time);
	}
	printf("--------All jobs are scheduled------\n");
	printf("Average waiting time: %.2f Average turnaround time: %.2f Average weighted turnaround time: %.2f", sum1 / num, sum2 / num, sum3 / num);
	initial_jobs_again();
}
int findNextHRRF(int pre)
{
	int current = 1, i, j;    //优先权=(等待时间+要求服务时间)/要求服务时间
	for (i = 1; i <= num; i++)
	{
		if (!jobs[i].visited) {
			jobs[i].wait_time = jobs[pre].finish_time - jobs[i].reach_time;    //等待时间=上一个进程的完成时间-到达时间
			jobs[i].excellent = (float)(jobs[i].wait_time + jobs[i].need_time) / jobs[i].need_time;
		}
	}
	for (i = 1; i <= num; i++)
	{
		if (!jobs[i].visited)
		{
			current = i;    //找到第一个还没完成的作业
			break;
		}
	}
	for (j = i; j <= num; j++)    //和后面的作业比较
	{
		if (!jobs[j].visited)    //还没完成(运行)
		{
			if (jobs[current].reach_time < jobs[pre].finish_time)    //如果进程在上一个进程完成之前到达
			{
				if (jobs[j].excellent > jobs[current].excellent)
					current = j;    //找出到达时间在上一个进程完成之前,优先权高的进程
			}
			else    //如果进程是在上一个进程完成之后到达
			{
				if (jobs[j].reach_time < jobs[current].reach_time)
					current = j;    //找出比较早到达的一个
				else if (jobs[j].reach_time == jobs[current].reach_time && jobs[j].excellent > jobs[current].excellent)    //如果同时到达
					current = j;    //找出服务时间比较短的一个
			}
		}
	}
	return current;    //返回当前进程
}
//高相应比优先
void HRRF() {
	int i, j;
	double sum1 = 0; //总的等待时间
	double sum2 = 0; //总的周转时间
	double sum3 = 0; //总的带权周转时间
	printf("High response ratio priority scheduling algorithm: \n");
	int pre = 1;
	jobs[1].finish_time = 0;

	for (i = 1; i <= num; i++) {
		int index = findNextHRRF(pre);
		printf("%dth work", index);
		printf("Arrival time --%d,service hours--%d\n",
			jobs[index].reach_time,
			jobs[index].need_time);
		printf("This job is running...........\n");
		_sleep(1);
		printf("Finish running\n");
		if (i == 1) {
			jobs[index].start_time = jobs[index].reach_time;
			jobs[index].finish_time = jobs[index].start_time + jobs[index].need_time;
			jobs[index].tr_time = jobs[index].need_time;
			jobs[index].wtr_time = 1.00;
			jobs[index].wait_time = 0;
		}
		else {
			if (jobs[index].reach_time > jobs[pre].finish_time) {
				jobs[index].wait_time = 0;
				jobs[index].start_time = jobs[index].reach_time;
			}
			else {
				jobs[index].start_time = jobs[pre].finish_time;
				jobs[index].wait_time = jobs[pre].finish_time - jobs[index].reach_time;
			}
			jobs[index].finish_time = jobs[index].start_time + jobs[index].need_time;
			jobs[index].tr_time = jobs[index].finish_time - jobs[index].reach_time;
			jobs[index].wtr_time = (double)jobs[index].tr_time / jobs[index].need_time;
		}
		jobs[index].visited = true;
		pre = index;
		sum1 += jobs[index].wait_time;
		sum2 += jobs[index].tr_time;
		sum3 += jobs[index].wtr_time;
		printf("waiting time: %d Turnaround time: %d Weighted turnaround time: %0.2f\n", jobs[index].wait_time, jobs[index].tr_time, jobs[index].wtr_time);
	}
	printf("--------All jobs are scheduled------\n");
	printf("Average waiting time: %.2f Average turnaround time: %.2f Average weighted turnaround time: %.2f", sum1 / num, sum2 / num, sum3 / num);
	initial_jobs_again();
}
//按照先来先服务并使用时间片轮转
vector<job> jobList;     //jobList向量

int time_unit = 10;//时间片长度
void initial_job_List() {    //给向量初始化
	for (int i = 1; i <= num; i++)
	{
		jobList.push_back(jobs[i]);
	}
}
bool cmp(job a, job b)
{
	return a.reach_time < b.reach_time;
}
void RR() {
	double sum1 = 0; //总的等待时间
	double sum2 = 0; //总的周转时间
	double sum3 = 0; //总的带权周转时间
	initial_job_List();
	queue<job>Ready;     //就绪队列
	sort(jobList.begin(), jobList.end(), cmp);
	int begin = (*jobList.begin()).reach_time;
	Ready.push(*jobList.begin());
	jobList.erase(jobList.begin());
	while (!jobList.empty() || !Ready.empty()) {
		while (!jobList.empty() && begin >= (*jobList.begin()).reach_time) { 	//有新作业到达,加入就绪队列
			Ready.push(*jobList.begin());
			jobList.erase(jobList.begin());
		}
		if (Ready.front().finish_time + time_unit < Ready.front().need_time) { 	//时间片用完没运行完,加入队尾
			printf("%d th Job executed %d\n", Ready.front().number, time_unit);
			Ready.front().finish_time += time_unit;
			begin += time_unit;
			while (!jobList.empty() && begin >= (*jobList.begin()).reach_time) { 	//有新作业到达,加入就绪队列
				Ready.push(*jobList.begin());
				jobList.erase(jobList.begin());
			}

			Ready.push(Ready.front());
			Ready.pop();
			_sleep(1);
		}
		else { //作业运行完
			if (Ready.front().need_time - Ready.front().finish_time < time_unit) {
				time_unit -= Ready.front().need_time - Ready.front().finish_time;
			}
			else {
				time_unit = 10;
			}
			printf("%d th Job executed %d\n", Ready.front().number, time_unit);
			begin += time_unit;
			Ready.front().finish_time = begin;
			Ready.front().wait_time = Ready.front().finish_time - Ready.front().reach_time - Ready.front().need_time;
			Ready.front().tr_time = Ready.front().finish_time - Ready.front().reach_time;
			Ready.front().wtr_time = (double)Ready.front().tr_time / Ready.front().need_time;
			sum1 += Ready.front().wait_time;
			sum2 += Ready.front().tr_time;
			sum3 += Ready.front().wtr_time;
			printf("The finished job is %d th work,waiting time is %d ,Turnaround time is %d ,Weighted turnaround time is %.2f\n", Ready.front().number, Ready.front().wait_time
				, Ready.front().tr_time, Ready.front().wtr_time);
			//从就绪队列中移除作业
			Ready.pop();

			if (Ready.empty() && !jobList.empty()) {
				sort(jobList.begin(), jobList.end(), cmp);
				printf("Find the current earliest job is: %d\n", (*jobList.begin()).number);
				begin = (*jobList.begin()).reach_time;
			}
			if (time_unit < 10) {
				time_unit = 10;
			}
			_sleep(1);
		}
	}
	printf("--------All jobs are scheduled------\n");
	printf("Average waiting time: %.2f Average turnaround time: %.2f Average weighted turnaround time: %.2f", sum1 / num, sum2 / num, sum3 / num);
	initial_jobs_again();
}
int findNextHPF(job j[MAX_NUM], int length, int time) {
	//优先值越低 表示优先权越高
	// p是已经到达且拥有最高优先权的进程的下标
	// q是没有到达的进程中拥有最早到达时间的进程的下标
	int i, p, q;
	int minReachTime, minPrivilege1;
	p = q = -1; minPrivilege1 = minReachTime = inf;
	for (i = 1; i <= length; i++) {
		if (!j[i].visited) {
			// 第一情况
			if (j[i].reach_time <= time && j[i].privilege <= minPrivilege1)
			{
				if (j[i].privilege == j[p].privilege) {   //如果优先权一致 则按最早抵达时间
					if (j[i].reach_time < j[p].reach_time) {
						p = i;
					}
				}
				else {
					p = i;
					minPrivilege1 = j[i].privilege;
				}
			}
			// 第二种情况
			else if (j[i].reach_time > time && j[i].reach_time <= minReachTime) {
				q = i; minReachTime = j[i].reach_time;
			}
		}
	}
	// p为-1时,代表在time时刻还没进程到达,此时选择下一个最早到达的进程q
	if (p != -1) return p;
	return q;
}
//优先权高者优先
void HPF() {
	int i, j;
	double sum1 = 0; //总的等待时间
	double sum2 = 0; //总的周转时间
	double sum3 = 0; //总的带权周转时间
	int finish = inf; //当前完成时间
	for (i = 1; i <= num; i++) {
		finish = min(finish, jobs[i].reach_time);
	}
	printf("High priority priority service (non-preemptive): \n");
	for (i = 1; i <= num; i++) {
		int index = findNextHPF(jobs, num, finish);
		printf("%dth work", index);
		printf("Arrival time --%d,service hours--%d\n",
			jobs[index].reach_time,
			jobs[index].need_time);
		printf("This job is running...........\n");
		_sleep(1);
		printf("Finish running\n");
		if (jobs[index].reach_time <= finish) {
			jobs[index].wait_time = finish - jobs[index].reach_time;
			jobs[index].start_time = finish;
		}
		else {
			jobs[index].start_time = jobs[index].reach_time;
			jobs[index].wait_time = 0;
		}
		jobs[index].finish_time = jobs[index].start_time + jobs[index].need_time;
		jobs[index].tr_time = jobs[index].finish_time - jobs[index].reach_time;
		jobs[index].wtr_time = (double)jobs[index].tr_time / jobs[index].need_time;
		jobs[index].visited = true;
		sum1 += jobs[index].wait_time;
		sum2 += jobs[index].tr_time;
		sum3 += jobs[index].wtr_time;
		finish = jobs[index].finish_time;
		printf("waiting time: %d Turnaround time: %d Weighted turnaround time: %0.2f\n", jobs[index].wait_time, jobs[index].tr_time, jobs[index].wtr_time);
	}
	printf("--------All jobs are scheduled------\n");
	printf("Average waiting time: %.2f Average turnaround time: %.2f Average weighted turnaround time: %.2f", sum1 / num, sum2 / num, sum3 / num);
	initial_jobs_again();
}

/主函数
int main() {
	initial_jobs(); //初始化所有作业信息
	read_Jobdata(); //读取数据文件
	int choice = 1;

	while (choice != 0) {
		printf("\nPlease select one of the scheduling algorithms:\n");
		printf("(1)FCFS\n");
		printf("(2)SJF\n");
		printf("(3)HRRF\n");
		printf("(4)HPF\n");
		printf("(0)Exit\n");
		printf("Please enter a number:");
		scanf("%d", &choice);
		switch (choice) {
		case 1:FCFS(); break;
		case 2:SJF(); break;
		case 3:HRRF(); break;
		case 4:HPF(); break;
		case 5:RR(); break;
		case 0:printf("Exit the program\n"); break;
		}
	}
	_keygo();
}

代码里有详细注释,测试文件要和源代码放在同一目录下:
eg
运行截图:

1
2
3
4

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Otto_1027

蟹蟹你,我会继续努力的~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值