• “短进程优先”调度算法


    实验一  进程调度

    一、实验目的

        编写并调试一个模拟的进程调度程序,以加深对进程的概念及进程调度算法的理解.

    二、实验内容

    1. 调试运行“短进程优先”调度算法,给出运行结果。
    2. 采用“短进程优先”调度算法对五个进程进行调度。每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、到达时间、需要运行时间、已用CPU时间、进程状态等等。
    3. 每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。

    三、实现思路

    1.  变量声明与结构体定义

    2.  输入函数

    3.  所有进程结束后,输出所有进程信息

    4.  找出运行时间最短的进程

    5. 进程执行完毕

    6. 主函数

     

    四、主要的数据结构

    1. 变量声明与结构体定义

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    /* run this program using the console pauser or add your own getch, system("pause") or input loop */

    struct pcb{

        char name[10];    //进程名

        int arrival_time; //进程到达时间()

        int start_time;   //进程开始时间

        int need_time;      //进程运行所需时间

        int finish_time;  //运行结束时间

        struct pcb * link;   //链接下一个pcb的指针

    };

    int num = 0;     //输入的进程数

    typedef struct pcb PCB;    //定义结构体变量

    /*

    结构体指针p指向 每新建的一个进程

    ready指针指向链表的第一个pcb

    finish指针指向完成队列的第一个pcb结构体

    */

    struct pcb *p = NULL, *ready = NULL, *finish = NULL;

    2. 输入函数

    //用来测试链表建立,输入链表结构体数据

    void print_test(){

        int i;

        struct pcb * test = ready;

        for(i=0;i<num;i++){

            printf(" 进程号:%d,进程名:%s,进程到达时间:%d,进程完成时间:%d",

                    i,test->name,test->arrival_time,test->need_time);

            if(NULL != test->link){

                test = test->link;

            }

            else{

                printf(" test_link end ");

            }

           

        }

    }

     

     

     

    //输入函数,建立链表

    void input(){

        int i;

        struct pcb * q;   //定义结构体变量

        printf("请输入进程数:");

        scanf("%d", &num);

        for(i=0; i<num; i++){

            printf(" 进程号 NO.%d:", i);

            p = (struct pcb*)malloc(sizeof(struct pcb));

            printf(" 输入进程名:");

            scanf("%s", p->name);

            printf(" 请输入进程到达时间:");

            scanf("%d", &p->arrival_time);

            printf(" 请输入进程运行时间:");

            scanf("%d", &p->need_time);

            

            p->link = NULL;

            //建立链表

            if(NULL == ready){   //建立第一个结构体,使指针p,q指向它

                ready = p;

                q = ready;

            }

            else{      //链表建立

                q->link = p;

                q = p;   

            }

            printf("input success");

        }

        print_test();   //测试链表是否建立

    }

    3.所有进程结束后,输出所有进程信息

    //输出当前运行进程相关数据或者打印暂无进程运行

    void output(struct pcb * p, int now_time){

        if(NULL == p){

            printf("当前时刻:%d, 暂无进程在运行! ", now_time);

        }

        else{

            printf("进程名:%s,到达时间:%d,运行需要时间:%d ",p->name,p->arrival_time,p->need_time);

        }

    }

    1. 4.  找出运行时间最短的进程

    //sjf  shortest job first最短作业优先

    struct pcb * SJF(int now_time, int * after){

        int min_time = 0;   //最短时间,即优先运行的进程的时间

        struct pcb * now_progress = NULL, *p = ready;

        //遍历链表,查找出运行时间最短的进程

        if (NULL != ready){

            while(NULL != p){

                if(now_time >= p->arrival_time){   //若进程已经到达,注意:时间单位为1

                    /*

                    min_time = p->need_time;      //是错误的

                    now_progress = p;

                    if(p->need_time < min_time){

                        min_time = p->need_time;

                        now_progress = p;

                    } */

                    if(0 == min_time){  //给最短时间赋初值

                        now_progress = p;

                        min_time = p->need_time;                   

                    }

                    else{

                        if(p->need_time < min_time){

                            now_progress = p;

                            min_time = p->need_time;

                        }

                    }

                }

                p = p->link;

            }

        }

        *after = min_time + now_time;

        printf(" SJF:a shortest progress running! ");

        return now_progress;   //返回指向正在运行进程的指针

    }

     

    5. 进程执行完毕

    //将已经运行完成的进程添加到finish队列,并且进程数减一

    void destory(struct pcb * p, int now_time){

        printf("destory start! ");

        struct pcb * q = ready;

        struct pcb * f = NULL;   //用于finish链表的添加

     

       

        if(strcmp(p->name, ready->name) == 0){  //若第一个进程完成

            ready = ready->link;

        }

        //若中间或最后一个进程完成

        else{

            q = ready;

            while((strcmp(q->link->name,p->name) != 0) && NULL != q->link){

                q = q->link;

            }

            q->link = p->link;

        }

       

         p->finish_time = now_time;    //结束时间

         p->start_time =  now_time - p->need_time;  //开始时间

        

        //将已经运行的进程添加到finish队列

        if(NULL == finish){

            finish = p;    //finish指向完成链表的表头

            p->link = NULL;

        }

        else{

            f = finish;

            while(NULL != f->link){

                f = f->link;

            }

            f->link = p;

            p->link = NULL;

        }

       

        num--;   //进程数减一

        printf(" destory success! ");

    }

    主函数

    int main(int argc, char *argv[]) {

       

       

        input();  //调用输入函数

       

        int now_time = 0;    //初始时间为0

        int after = 0;        //执行完一个进程后的时间:优先运行进程的运行时间+当前时间

        struct pcb * now_progress = NULL;    //now_progress指向正在运行的进程(结构体)

        struct pcb *m = NULL;

       

        while(num > 0){    //进程数大于0,每次循环num会减一

            printf("start SJF");

            now_progress = SJF(now_time, &after);  //调用SJF函数,遍历链表

     

           

            if(NULL != now_progress){

                /*进程执行,每循环一次,当前时间加一

                  同时要判断当前时间是否有进程刚好到达正在在等待 */

                for(;now_time < after; now_time++){

                    printf(" 当前时刻:%d", now_time);

                    printf(" -----------当前执行进程------------ ");

                    output(now_progress, now_time);     //调用output函数

                    printf(" -----------等待执行进程------------ ");

                   

                    m = ready;

                    while(NULL != m){   //循环,若当前时间有进程到达,打印相关信息

                        if(m != now_progress){

                            if(m->arrival_time <= now_time){

                                output(m, now_time);

                                printf(" a new progress arrival ");

                            }

                        }

                        m = m->link;

                    }

                }

                //进程执行完后调用destory函数

                destory(now_progress, now_time);

     

            }

            else{   //没有进程在运行

                output(now_progress, now_time);

                now_time++;

            }

           

        }

        output_all();

        return 0;

       

    }

    五、算法流程图

    六、运行与测试(系统运行截图)

     

     

     

     

     

    七、总结

    SJF算法是以进程的运行时间长度作为优先级,进程运行时间越短,优先级越高。

    缺点

    必须预知进程的运行时间。即使是程序员也很难准确估计进程运行时间。如果估计过低,系统就可能按估计的时间终止进程的运行,但此时进程并未完成,故一般都会偏长估计

    对长进程不利。长进程的周转时间会明显地增长。可怕的是,SJF算法完全忽视进程等待时间,可能使进程等待时间过长,出现饥饿现象。

    人机无法实现交互。

    完全未考虑进程的紧迫程度。不能保证紧迫性进程得到及时处理。

    问题:对比说明短进程优先和动态优先数中PCB的定义有什么不同?

    不积跬步,无以至千里;不积小流,无以成江海。
  • 相关阅读:
    [转载]企业级服务器设计与实现经验之系统框架(一)
    【转载】es通信框架
    【转载】企业级服务器设计与实现经验之插件系统基础篇
    阻塞队列
    [转载]ESFramework 4.0 进阶(01)-- 消息
    心跳监测器 IHeartBeatChecker
    poj2470
    poj2478
    poj2418
    poj2481
  • 原文地址:https://www.cnblogs.com/CCTVCHCH/p/14923542.html
Copyright © 2020-2023  润新知