需求
用四种方法模拟进程调度,分别是:
- FCFS (Non-preemptive)—— 先来先处理(非抢占)
- Shortest Job First (Non-preemptive)——最短任务优先(非)
- Shortest Remaining Time First (Preemptive)——剩余最短优先(抢占)
- Round Robin : Time Quantum = 2 (Preemptive)——时间片轮转(抢)
已经给出主函数,main.c
#include <stdio.h>
#include <stdlib.h>
#include "schedule.h"
// global variables
int tick = 0;
int main(int argc, char* argv[])
{
char file_name[1024] = "";
int schedule_method = -1;
printf("Enter process file name:");
scanf("%s", file_name);
printf("Enter process scheduling mehtod \n");
printf("1: FCFS: First Come First Served (Non-preemptive) \n");
printf("2: SJF: Shortest Job First (Non-preemptive) \n");
printf("3: SRTF: Shortest Remaining Time First (Preemptive) \n");
printf("4: RR: Round Robin (Non-preemptive) \n");
scanf("%d", &schedule_method);
set_schedule(schedule_method);
// set processes
read_proc_list(file_name);
while(1){
int res = do_schedule(tick);
if (res == 0 || tick > 1000) break;
tick++;
}
print_performance();
return 0;
}
给出schedule.h,定义好了头文件,四个函数需要自己实现
#ifndef __schedule_h__
#define __schedule_h__
// fn: read_proc_list
// desc: read process file list
// param
// file_name: process list name
void read_proc_list(const char* file_name);
// fn: set_schedule
// desc: set scheduling method
//
// param: method
// scheduling method
// 1. FCFS (Non-preemptive)
// 2. Shortest Job First (Non-preemptive)
// 3. Shortest Remaining Time First (Preemptive)
// 4. Round Robin : Time Quantum = 2 (Preemptive)
// return none
void set_schedule(int method);
// fn: set_schedule
// desc: set scheduling method
//
// param: method
// scheduling method
// 1. FCFS (Non-preemptive)
// 2. Shortest Job First (Non-preemptive)
// 3. Shortest Remaining Time First (Preemptive)
// 4. Round Robin : Time Quantum = 2 (Preemptive)
// return none
int do_schedule(int tick);
// fn: print_performance();
// desc: print system performance
void print_performance();
#endif
给出了数据输入的格式proc_list.txt
还要求打印相关信息
选择方法的信息、进程到来的信息、进程切换、所有进程结束
原理
网上一堆
https://blog.csdn.net/qq_35642036/article/details/82809812
实现
定义一些数据
#include <stdio.h>
#include <stdlib.h>
#include "schedule.h"
#define MAX_N 11
int total_process=0,mode=-1;
struct node {
int pid;//进程号
int arrive;//到达时间
int brust;//持续时间
int start;//真正开始时间
int finish;//结束时间
int remain;//该任务剩余时间
} nodes[MAX_N];
每次时钟驱动进来,都执行以下程序,查看新加进来的进程
void check_new(int idx_process,int tick){
int n;
for(n=0;n<total_process;n++){
if(nodes[n].arrive==tick)
printf("[tick: %02d] New Process (ID: %d) newly joins to ready queue\n"\
,tick,nodes[n].pid);
}
}
读文件没啥好说的,数组形式保存。
void read_proc_list(const char* file_name){
FILE *fp_inlist = fopen(file_name,"r");
fscanf(fp_inlist,"%d",&total_process);
for(int i=0;i<total_process;i++){
fscanf(fp_inlist,"%d %d %d",&nodes[i].pid,&nodes[i].arrive,&nodes[i].brust);
//printf("%d %d %d\r\n",nodes[i].pid,nodes[i].arrive,nodes[i].brust);
nodes[i].finish=-1;
nodes[i].start=-1;
nodes[i].remain=nodes[i].brust;
}
fclose(fp_inlist);
}
设置调度模式,就是把一个全局变量设置成1234
void set_schedule(int method){
mode=method;
switch (mode)
{
case 1:
printf("Scheduling method: FCFS (Non-preemptive)\n");
break;
case 2:
printf("Scheduling method: Shortest Job First (Non-preemptive)\n");
break;
case 3:
printf("Scheduling method: Shortest Remaining Time First (Preemptive)\n");
break;
case 4:
printf("Scheduling method: Round Robin : Time Quantum = 2 (Preemptive)s)\n");
break;
}
return;
}
主函数中,while模拟系统时钟驱动do_schedul函数执行。
mode1:就是先到先行,一次读取各个任务就行
mode2:最短作业,每次查找未完成任务中的最短任务,加以处理,并直接处理完,要注意的是,next查找前初始化为-1,。
mode3:查找剩余任务最短的,每次时钟触发调度都要查找。
mode4:时间片,长度2,时间结束或者本次任务完成都去切换,要维护一个队列,用数组写了一个队列。
static int idx_process=-1,remain_time=10000,i,min_t,next,now=1,last_search_idx=0;
static int queue[100],p=0,q=0;
int do_schedule(int tick){
int n;
switch(mode)
{
case 1:
remain_time--;
if(idx_process==-1 || remain_time==0){//第一次启动程序,或上一次到点了
if(idx_process!=-1){
printf("[tick: %02d] Dispatch to Process (ID: %d) \n",tick,nodes[idx_process].pid);
nodes[idx_process].finish=tick;
}
idx_process++;
if(idx_process>=total_process){
printf("[tick: %02d] All processes are terminated\n",tick);
return 0;
}
remain_time=nodes[idx_process].brust;
printf("[tick: %02d] New Process (ID: %d) newly joins to ready queue\n"\
,tick,nodes[idx_process].pid);
nodes[idx_process].start=tick;
}
break;
case 2:
remain_time--;
check_new(idx_process,tick);
if(idx_process==-1|| remain_time==0){
if(idx_process!=-1){//当前退出
nodes[idx_process].finish=tick;
}
//在所有等待近程中找没开的的最短的
next=-1;
min_t=10000;
for(i=0;i<total_process;i++){
if(nodes[i].start==-1 && nodes[i].brust<min_t && nodes[i].arrive<=tick){
min_t=nodes[i].brust;
next=i;
}
}
if(next==-1){
printf("[tick: %02d] All processes are terminated\n",tick);
return 0;
}
idx_process=next;
nodes[next].start=tick;
remain_time=nodes[next].brust;
printf("[tick: %02d] Dispatch to Process (ID: %d) \n",tick,nodes[next].pid);
}
break;
case 3:
if(idx_process!=-1){
nodes[idx_process].remain--;
if(nodes[idx_process].remain==0)
nodes[idx_process].finish=tick;
}
check_new(idx_process,tick);
//在所有等待近程中找没开的的最短的
next=-1;
min_t=10000;
for(i=0;i<total_process;i++){
if(nodes[i].remain!=0 && nodes[i].remain<min_t && nodes[i].arrive<=tick){
next=i;
min_t=nodes[i].remain;
}
}
if(next==-1){
printf("[tick: %02d] All processes are terminated\n",tick);
return 0;
}
if(nodes[next].start==-1)
nodes[next].start=tick;
if(idx_process!=next){
idx_process=next;
printf("[tick: %02d] Dispatch to Process (ID: %d) \n",tick,nodes[idx_process].pid);
}
break;
case 4:
check_new(idx_process,tick);
for(n=0;n<total_process;n++){
if(nodes[n].arrive==tick){
queue[q]=n;
q++;
}
}
now++;
if(idx_process!=-1){//本次任务时间剩余减一
nodes[idx_process].remain--;
}
if(idx_process!=-1 &&nodes[idx_process].remain==0){//本次任务完
nodes[idx_process].finish=tick;//本次任务完
if(p==q){
printf("[tick: %02d] All processes are terminated\n",tick);
return 0;
}
printf("[tick: %02d] Dispatch to Process (ID: %d) \n",tick,nodes[queue[p]].pid);
idx_process=queue[p];
if(nodes[idx_process].start==-1)
nodes[idx_process].start=tick;
p++;
now=0;
break;
}
if(now==2){//时间片结束
now=0;
if(nodes[idx_process].remain!=0){
queue[q]=idx_process;
q++;
}else{
nodes[idx_process].finish=tick;//本次任务完
}
if(p==q){
printf("[tick: %02d] All processes are terminated\n",tick);
return 0;
}else{
if(idx_process!=queue[p]){
printf("[tick: %02d] Dispatch to Process (ID: %d) \n",tick,nodes[queue[p]].pid);
}
idx_process=queue[p];
if(nodes[idx_process].start==-1)
nodes[idx_process].start=tick;
p++;
}
}
break;
default:
break;
};
return 1;
}
显示函数,控制台打印,注意数据类型
void print_performance(){
int i,trt=0,wt=0,rt=0;
printf("\n======================================================================\n");
printf("PID arrive finish brust Turn around time Wait time Respponse time\n");
printf("=======================================================================\n");
for(i=0;i<total_process;i++){
printf("%02d ",nodes[i].pid);
printf("%02d ",nodes[i].arrive);
printf("%02d ",nodes[i].finish);
printf("%02d ",nodes[i].brust);
trt+=(nodes[i].finish-nodes[i].arrive);
printf("%02d ",nodes[i].finish-nodes[i].arrive);
rt+=(nodes[i].finish-nodes[i].arrive-nodes[i].brust);
printf("%02d ",nodes[i].finish-nodes[i].arrive-nodes[i].brust);
wt+=(nodes[i].start-nodes[i].arrive);
printf("%02d\n",nodes[i].start-nodes[i].arrive);
}
printf("-----------------------------------------------------------------------\n");
printf("average: %5.2f %5.2f %5.2f\n",\
(float)trt/ (float)total_process, (float)rt/ (float)total_process, (float)wt/ (float)total_process);
printf("=======================================================================\n");
}
效果