进程调度算法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");
}