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