模拟任务调度算法 C语言 【留学生作业】

需求

用四种方法模拟进程调度,分别是:

  1. FCFS (Non-preemptive)—— 先来先处理(非抢占)
  2. Shortest Job First (Non-preemptive)——最短任务优先(非)
  3. Shortest Remaining Time First (Preemptive)——剩余最短优先(抢占)
  4. 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");
}

效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清欢_小铭

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值