进程调度算法C语言实现

进程调度算法C语言实现

#define _CRT_SECURE_NO_WARNINGS
#define NUMBER 5

#include <stdio.h>
#include <windows.h>
char process_name[NUMBER] = { 'A', 'B', 'C', 'D', 'E' };
int arrive_time[NUMBER] = { 0, 2, 2, 3, 4 };
int server_time[NUMBER] = { 1, 3, 5, 2, 4 };
int fcfs_finished[NUMBER];
int fcfs_work[NUMBER];
double a_fcks_work[NUMBER];
typedef struct name_server{
	char process_name;
	int arrive_time;
	int server_time;
	int finished;
	int work;
	double a_work;
	double prioprity;
	int is_finished;//代表轮转周期结束时,当前进程是否结束
};


void init_data(name_server *init_data);
void chang_position(name_server *temp_name_server, int index, int temp_value);
void calc_work_or_a_work(name_server *new_name_server_psa);
void print(name_server print_struct[5]);
void recovery_order(name_server *new_name_server, name_server *old_name_server);
void fcfs();
void sjf();
void psa();


//先来先服务
void fcfs() {
	name_server name_server_fcfs[NUMBER];
	//初始化
	init_data(name_server_fcfs);
	int is_true = 1;
	int temp_sum = 0;
	int is_wait = 0;
	while (is_true){
		//完成时间
		int is_finished = 0;
		for (int i = 0; i<NUMBER; i++) {
			//当时间无法达到到达时刻时执行
			if (is_wait > NUMBER+1) {
				temp_sum++;
				is_wait = 0;
				break;
			}

			//判断是否到达
			if (name_server_fcfs[i].arrive_time > temp_sum) {
				is_wait++;
				continue;
			}

			if (name_server_fcfs[i].is_finished == 1){
				is_finished++;
				is_wait++;
				if (is_finished == NUMBER){
					is_true = 0;
					break;
				}
				continue;
			}
		

			//完成时间
			name_server_fcfs[i].finished = temp_sum + name_server_fcfs[i].server_time;
			temp_sum += name_server_fcfs[i].server_time;
			name_server_fcfs[i].is_finished = 1;
			is_wait = 0;
			break;
		}
	}

	calc_work_or_a_work(name_server_fcfs);
}

//短作业优先
void sjf() {
	//初始化一个进程名与服务时间有关的结构体
	name_server name_server_sjf[NUMBER];
	//初始化数据
	init_data(name_server_sjf);

	//完成时间的计算
	int temp_sum = 0;
	double avg_work = 0.0;
	double avg_a_work = 0.0;
	for (int j = 0; j < NUMBER; j++) {//循环进程的次数
			if (j == 0) {//0时刻进入的进程先执行
				name_server_sjf[j].finished = temp_sum + name_server_sjf[j].server_time;
			}
			else{
				//循环遍历查找是否满足到达时间
				int temp = 0;
				for (int i = j;i<NUMBER-j;i++){
					if (name_server_sjf[i].arrive_time > temp_sum){
						temp++;
					}
				}
				//不满足到达条件进入下次循环,等待进程到达
				if(temp == NUMBER - j - 1){
					if (j < NUMBER - 1){
						j--;
						temp_sum++;
						continue;
					}
				}

				int min_index = j;
				//查找剩余进程中最小的服务时间的进程
				for (int i = j + 1; i<NUMBER; i++) {
					name_server min = name_server_sjf[min_index];


					//判断是否到达
					if (name_server_sjf[i].arrive_time > temp_sum){
						//进入每次对比的最后一次,进行向前替换
						if (i == NUMBER-1) {
							//交换位置
							chang_position(name_server_sjf, min_index, j);
						}
						continue;
					}

					if (min.server_time > name_server_sjf[i].server_time) {
						min_index = i;
					}

					if (i == NUMBER-1) {
						//交换位置
						chang_position(name_server_sjf, min_index, j);
					}
				
				}
				name_server_sjf[j].finished = temp_sum + name_server_sjf[j].server_time;
			}
			temp_sum += name_server_sjf[j].server_time;
	}
	
	//恢复进程名的顺序
	name_server new_name_server_sjf[NUMBER];
	recovery_order(new_name_server_sjf, name_server_sjf);

	//输出计算后的数据
	calc_work_or_a_work(new_name_server_sjf);
}	

//优先级
void psa() {
	//初始化一个进程名与服务时间有关的结构体
	name_server name_server_psa[NUMBER];
	//初始化数据
	init_data(name_server_psa);

	//总完成时间
	int temp_sum = 0;
	for (int i = 0; i<NUMBER; i++) {
		if (i == 0) {
			name_server_psa[i].finished = arrive_time[i] + server_time[i];
			temp_sum += name_server_psa[i].finished;
		}
		else {

			//循环遍历查找是否满足到达时间
			int temp = 0;
			for (int j = i; j<NUMBER - i; j++){
				if (name_server_psa[j].arrive_time > temp_sum){
					temp++;
				}
			}
			//不满足到达条件进入下次循环,等待进程到达
			if (temp == NUMBER - i - 1){
				if (i < NUMBER - 1){
					i--;
					temp_sum++;
					continue;
				}
			}

			//计算优先级
			for (int j = i; j < NUMBER; j++) {
				name_server_psa[j].prioprity = (name_server_psa[i - 1].finished - name_server_psa[j].arrive_time + name_server_psa[j].server_time)/ (name_server_psa[j].server_time*1.0);
			}
			//找出当次循环的最大优先级
			name_server max = name_server_psa[i];
			int max_index = i;
			for (int j = i + 1; j < NUMBER; j++) {
				//判断是否到达
				if (name_server_psa[i].arrive_time > temp_sum){
					//前移最大优先级
					if (j == NUMBER-1) {
						//交换位置
						chang_position(name_server_psa, max_index, i);
					}
					continue;
				}

				if (max.prioprity < name_server_psa[j].prioprity) {
					max = name_server_psa[j];
					max_index = j;
				}

				//前移最大优先级
				if (j == NUMBER-1) {
					//交换位置
					chang_position(name_server_psa, max_index, i);
				}
			}
			//计算完成时间
			name_server_psa[i].finished = temp_sum + name_server_psa[i].server_time;
			temp_sum += name_server_psa[i].server_time;
		}
	}

	//恢复进程名的顺序
	name_server new_name_server_psa[NUMBER];
	recovery_order(new_name_server_psa, name_server_psa);

	//计算带输出
	calc_work_or_a_work(new_name_server_psa);
}

//轮转调度算法
void rr() {
	name_server name_server_rr[NUMBER];
	init_data(name_server_rr);

	int r_r = 4;

	int finished_circle = 1;
	int circle_times = 1;
	int temp_sum = 0;
	while (finished_circle) {
		finished_circle = 0;
		for (int i = 0; i < NUMBER; i++) {
			//循环遍历查找是否满足到达时间
			int temp = 0;
			for (int j = i; j<NUMBER - i; j++){
				if (name_server_rr[j].arrive_time > temp_sum){
					temp++;
				}
			}
			//不满足到达条件进入下次循环,等待进程到达
			if (temp == NUMBER - i - 1){
				//当不是第一个数据的时候
				if (i != 0){
					if (i < NUMBER - 1){
						i--;
						temp_sum++;
						continue;
					}
				}
				
			}
			if (name_server_rr[i].is_finished == 1) {
				continue;
			}
			//判断是否出现周期大于服务时间的情况
			if ((name_server_rr[i].server_time - (circle_times - 1)*r_r) <= r_r) {
				temp_sum += (name_server_rr[i].server_time - (circle_times-1)*r_r);
			}
			else{
				temp_sum += r_r;
			}
			//判断是否为结束状态
			if ((circle_times*r_r) >= name_server_rr[i].server_time) {
				name_server_rr[i].is_finished = 1;
				name_server_rr[i].finished = temp_sum;
			}
			//继续循环
			if (name_server_rr[i].server_time > (circle_times*r_r)) {
				finished_circle = 1;
			}
		}
		circle_times++;
	}

	//计算带输出
	calc_work_or_a_work(name_server_rr);

}

//多级反馈队列
void mfq() {
	//用于最后存储完成时间和计算使用
	name_server copy_name_server_mfq[NUMBER];
	//用于计算操作使用
	name_server name_server_mfq[NUMBER];
	init_data(copy_name_server_mfq);
	init_data(name_server_mfq);

	int r_r = 1;
	int temp_sum = 0;
	int num_queue = 0;
	while (true) {
		if (temp_sum != 0){
			r_r *= 2;
		}
		printf("----------------------\n");
		num_queue++;
		printf("%d队列:\n", num_queue);
		int temp = 0;
		for (int i = 0; i<NUMBER; i++) {

			//循环遍历查找是否满足到达时间
			int is_temp = 0;
			for (int j = i; j<NUMBER - i; j++){
				if (name_server_mfq[j].arrive_time > temp_sum){
					is_temp++;
				}
			}
			//不满足到达条件进入下次循环,等待进程到达
			if (is_temp == NUMBER - i - 1){
				//当不是第一个数据的时候
				if (i != 0){
					if (i < NUMBER - 1){
						i--;
						temp_sum++;
						continue;
					}
				}

			}
			//判断此进程是否运行结束
			if (name_server_mfq[i].server_time == 0) {
				temp++;
				continue;
			}
			//判断当前时间就进程是否到达
			if (name_server_mfq[i].arrive_time > temp_sum) {
				continue;
			}
			//判断此进程是否在当前就绪队列结束
			if (name_server_mfq[i].server_time <= r_r ) {
				temp_sum += name_server_mfq[i].server_time;
				printf("%c进程在此队列运行%d时间,%c进程运行完毕!\n",
					name_server_mfq[i].process_name, 
					name_server_mfq[i].server_time,
					name_server_mfq[i].process_name);
				name_server_mfq[i].server_time = 0;
				copy_name_server_mfq[i].finished = temp_sum;
			}
			else{
				temp_sum += r_r;
				name_server_mfq[i].server_time -= r_r;
				printf("%c进程在此队列运行%d时间\n", name_server_mfq[i].process_name, r_r);
			}
		}

		//判断进程就绪队列是否为空
		if (temp == NUMBER) {
			break;
		}
	}
	//计算周转时间和带权周转时间
	calc_work_or_a_work(copy_name_server_mfq);
}

//初始化数据
void init_data(name_server *init_data){
	for (int i = 0; i < NUMBER; i++) {
		init_data[i].process_name = process_name[i];
		init_data[i].arrive_time = arrive_time[i];
		init_data[i].server_time = server_time[i];
		init_data[i].is_finished = 0;
	}
}

//交换位置
void chang_position(name_server *temp_name_server, int index, int temp_value){
	name_server temp = temp_name_server[index];
	temp_name_server[index] = temp_name_server[temp_value];
	temp_name_server[temp_value] = temp;
}

//恢复进程名顺序
void recovery_order(name_server *new_name_server, name_server *old_name_server) {
	for (int i = 0; i<NUMBER; i++) {
		new_name_server[old_name_server[i].process_name - 'A'] = old_name_server[i];
	}
}

//计算周转时间和带权周转时间
void calc_work_or_a_work(name_server *new_name_server) {
	double avg_work = 0.0;
	double avg_a_work = 0.0;
	for (int i = 0; i<NUMBER; i++) {
		//周转时间
		new_name_server[i].work = new_name_server[i].finished - new_name_server[i].arrive_time;
		//总周转时间
		avg_work += new_name_server[i].work;
		//带权周转时间
		new_name_server[i].a_work = (new_name_server[i].work * 1.0) / new_name_server[i].server_time;
		//总带权周转时间
		avg_a_work += new_name_server[i].a_work;
	}

	print(new_name_server);
	printf("平均周转时间:%5.2f\n", avg_work / 5);
	printf("平均带权周转时间:%5.2f\n", avg_a_work / 5);
}

//输出数据
void print(name_server print_struct[NUMBER]){
	printf("进程名 到达时间 服务时间 完成时间 周转时间 带权周转时间\n");
	for (int i = 0; i<NUMBER; i++){
		printf("%c\t%d\t%-7d\t%-8d\t%-d\t%.2f\n", print_struct[i].process_name,
			print_struct[i].arrive_time,
			print_struct[i].server_time,
			print_struct[i].finished,
			print_struct[i].work,
			print_struct[i].a_work);
	}
}

//选项跳转
void choice_ui(int choice){
	switch (choice) {
	case 1:
		fcfs();
		break;
	case 2:
		sjf();
		break;
	case 3:
		psa();
		break;
	case 4:
		rr();
		break;
	case 5:
		mfq();
		break;
	default:
		printf("输入有误!");
	}
	system("pause");
}


void main() {
	int choice;
	while (1) {
		printf("选择查看的作业调度算法:\n");
		printf("1、先来先服务(fcfs)\n");
		printf("2、短作业优先(sjf)\n");
		printf("3、优先调度算法(psa)\n");
		printf("4、轮转调度算法(rr)\n");
		printf("5、多级反馈队列调度算法\n");
		scanf("%d",&choice);
		choice_ui(choice);
		system("cls");
	}
	system("pause");
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章