zoukankan      html  css  js  c++  java
  • 进程调度模拟程序

    1.    目的和要求

    1.1.           实验目的

    用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。

    1.2.           实验要求

    1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序。

    进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。

    (1).  每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。

    (2).  进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。

    (3).  每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。

    (4).  就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。

    (5).  如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。

    (6).  每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。   

    (7).  重复以上过程,直到所要进程都完成为止。

    1.2.2实验题A:编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对N(N不小于5)个进程进行调度。

    “最高优先级优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。

    (1). 静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。

    (2). 动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定规则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1,并且进程等待的时间超过某一时限(2个时间片时间)时增加其优先数等。

    (3). (**) 进程的优先数及需要的运行时间可以事先人为地指定,(也可以由随机数产生)。

    (4). (**)在进行模拟调度过程可以创建(增加)进程,其到达时间为进程输入的时间。

    1.2.3实验题B:编写并调试一个模拟的进程调度程序,采用“基于时间片轮转法”调度算法对N(N不小于5)个进程进行调度。 “轮转法”有简单轮转法、多级反馈队列调度算法。

    (1). 简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片长度相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。(此调度算法是否有优先级?)

     (2). 多级反馈队列调度算法的基本思想是:

    将就绪队列分为N级(N=3~5),每个就绪队列优先数不同并且分配给不同的时间片:队列级别越高,优先数越低,时间片越长;级别越小,优先数越高,时间片越短。

    系统从第一级调度,当第一级为空时,系统转向第二级队列,.....当处于运行态的进程用完一个时间片,若未完成则放弃CPU,进入下一级队列。

    当进程第一次就绪时,进入第一级队列。

    (3). (**)考虑进程的阻塞状态B(Blocked)增加阻塞队列。进程的是否阻塞和阻塞的时间由产生的“随机数”确定(阻塞的频率和时间长度要较为合理)。注意进程只有处于运行状态才可能转换成阻塞状态,进程只有处于就绪状态才可以转换成运行状态。

    2.    实验内容

    根据指定的实验课题:A(1),A(2),B(1)和B(2)

    完成设计、编码和调试工作,完成实验报告。

    注:带**号的条目表示选做内容。

     3.    实验环境

    可以选用Turbo C作为开发环境。也可以选用Windows下的VB,CB等可视化环境,利用各种控件较为方便。自主选择实验环境。

    4.    实验原理及核心算法参考程序段

         动态优先数(优先数只减不加):

    5.参考代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    
    struct PCB{
        char p_name[20];
        int p_priority;
        int p_needTime;a
        int p_runTime;
        char p_state;
        struct PCB* next;
    };
    
    void HighPriority();
    void RoundRobin();
    void Information();
    char Choice();
    struct PCB* SortList(PCB* HL);
    
    int main()
    {
        Information();
        char choice = Choice();
        switch(choice)
        {
            case '1':
                system("cls");
                HighPriority();
                break;
            case '2':
                system("cls");
                RoundRobin();
                break;
            default:
                break;
        }
        system("pause");
        return 0;
    }
    
    void Information()
    {
        printf("
    
    ");
        printf("              *********************************************             
    ");
        printf("                            模拟进程调度算法
    ");
        printf("              *********************************************             
    
    
    ");    
        printf("                       班    级:  网络工程班
    ");
        printf("                       姓    名:  张文雅
    ");
        printf("                       学    号:  201306114136
    ");
        printf("                       实验日期: 2015年05月17日
    
    
    
    
    
    ");
        printf("                         按回车键进入演示程序");
        getchar();
        system("cls");
    }
    char Choice()
    {
        printf("
    
    ");
        printf("              *********************************************             
    ");
        printf("                              进程调度演示
    ");
        printf("              *********************************************             
    
    
    ");    
        printf("                        1.演示最高优先数优先算法。
    ");
        printf("                        2.演示轮转法算法。
    ");
        printf("                        3.退出程序。
    
    
    
    ");
        printf("                            选择进程调度方法:");     
        char ch = getchar();
        return ch;
        system("cls");
    }
    void HighPriority()
    {
        struct PCB *processes, *pt;
        //pt作为临时节点来创建链表
        processes = pt = (struct PCB*)malloc(sizeof(struct PCB));    
        for (int i = 0; i != 5; ++i)
        {
            struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));
            printf("进程号No.%d:
    ", i);
            printf("输入进程名:");
            scanf("%s", p->p_name);
            printf("输入进程优先数:");
            scanf("%d", &p->p_priority);
            printf("输入进程运行时间:");
            scanf("%d", &p->p_needTime);
            p->p_runTime = 0;
            p->p_state = 'W';
            p->next = NULL;
            pt->next = p;
            pt = p;
            printf("
    
    ");
        }
        getchar();  //接受回车
        //processes作为头结点来存储链表
        processes = processes->next;
        int cases = 0;
        struct PCB *psorted = processes;
        while (1)
        {
            ++cases;
            pt = processes; 
            //对链表按照优先数排序
            //psorted用来存放排序后的链表
            psorted = SortList(psorted);
            printf("The execute number: %d
    
    ", cases);
            printf("**** 当前正在运行的进程是:%s
    ", psorted->p_name);
            psorted->p_state = 'R';
            printf("qname    state    super    ndtime    runtime
    ");
            printf("%s	%c	%d	%d	%d	
    
    ", psorted->p_name, psorted->p_state, psorted->p_priority, psorted->p_needTime, psorted->p_runTime);
            pt->p_state = 'W';
            psorted->p_runTime++;
            psorted->p_priority--;
            printf("**** 当前就绪状态的队列为:
    
    ");
            //pt指向已经排序的队列
            pt = psorted->next;
            while (pt != NULL)
            {
                printf("qname    state    super    ndtime    runtime
    ");
                printf("%s	%c	%d	%d	%d	
    
    ", pt->p_name, pt->p_state, pt->p_priority, pt->p_needTime, pt->p_runTime);
                pt = pt->next;
            }
            //pt指向已经排序的链表,判断链表是否有已用时间啊等于需要时间的
            pt = psorted;
            struct PCB *ap;
            ap = NULL; //ap指向pt的前一个节点
            while (pt != NULL)
            {
                if (pt->p_needTime == pt->p_runTime)
                {
                    if (ap == NULL)
                    {
                        pt = psorted->next;
                        psorted = pt;
                    }
                    else
                        ap->next = pt->next;
                }
                ap = pt;
                pt = pt->next;
            }
            if (psorted->next == NULL)
                break;
            getchar();
        }
    }
    struct PCB* SortList(PCB* HL)
    {
        struct PCB* SL;
        SL = (struct PCB*)malloc(sizeof(struct PCB));
        SL = NULL;
    
        struct PCB* r = HL;
        while (r != NULL)
        {
            struct PCB* t = r->next;
            struct PCB* cp = SL;
            struct PCB* ap = NULL;
            while (cp != NULL)
            {
                if (r->p_priority > cp->p_priority)
                    break;
                else
                {
                    ap = cp;
                    cp = cp->next;
                }
            }
            if (ap == NULL)
            {
                r->next = SL;
                SL = r;
            }
            else
            {
                r->next = cp;
                ap->next = r;
            }
            r = t;
        }
        return SL;
    }
    //轮转算法
    void RoundRobin()
    {
        struct PCB *processes, *pt;
        //pt作为临时节点来创建链表
        processes = pt = (struct PCB*)malloc(sizeof(struct PCB));    
        for (int i = 0; i != 5; ++i)
        {
            struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));
            printf("进程号No.%d:
    ", i);
            printf("输入进程名:");
            scanf("%s", p->p_name);
            printf("输入进程运行时间:");
            scanf("%d", &p->p_needTime);
            p->p_runTime = 0;
            p->p_state = 'W';
            p->next = NULL;
            pt->next = p;
            pt = p;
            printf("
    
    ");
        }
        getchar();  //接受回车
        //processes作为头结点来存储链表
        processes = processes->next;
        int cases = 0;
        while (1)
        {
            ++cases;
            pt = processes; 
            printf("The execute number: %d
    
    ", cases);
            printf("**** 当前正在运行的进程是:%s
    ", pt->p_name);
            pt->p_state = 'R';
            printf("qname    state    super    ndtime    runtime
    ");
            printf("%s	%c	%d	%d	%d	
    
    ", pt->p_name, pt->p_state, pt->p_priority, pt->p_needTime, pt->p_runTime);
            pt->p_state = 'W';
            pt->p_runTime++;
            pt->p_priority--;
            printf("**** 当前就绪状态的队列为:
    
    ");
            pt = pt->next;
            while (pt != NULL)
            {
                printf("qname    state    super    ndtime    runtime
    ");
                printf("%s	%c	%d	%d	%d	
    
    ", pt->p_name, pt->p_state, pt->p_priority, pt->p_needTime, pt->p_runTime);
                pt = pt->next;
            }
            //检测是否运行时间等于需要时间,是的话从队列里面删除,不是的话加到队列最尾部
            pt = processes;
            if (pt->p_needTime == pt->p_runTime)
            {
                pt->p_state = 'C';
                pt = processes->next;
                processes = pt;
            }
            else
            {
                if (pt ->next != NULL)
                {
                    //寻找最后一个节点
                    while (pt->next != NULL)
                        pt = pt->next;
                    struct PCB* ptem;//临时节点用来帮助把头结点插到尾部
                    ptem = processes->next;
                    pt->next = processes;
                    processes->next = NULL;
                    processes = ptem;
                }
            }
            pt = processes;
            if (pt == NULL)
                break;
            getchar();
        }
    }



    运行结果:
    x



     实验总结:编代码需要细心以及耐心,一开始错误连连,通过参考资料,不断修整代码,不厌其烦地纠正一个个错误,直至运行成功与运算正确,这个过程虽略有辛苦,但也充满了欢乐,正是所谓的乐在苦中吧。

  • 相关阅读:
    不忘初心,方得始终
    我的博客开通了~第一个帖子奉上
    @TableLogic表逻辑处理注解(逻辑删除)
    nginx笔记
    ERROR: permission denied for relation hycom 权限被拒绝
    Mybatis-plus学习笔记
    SpringBoot学习笔记
    org.apache.ibatis.binding.BindingException原因总结(找不到映射文件)
    SpringBoot优先加载设置
    Date时间处理
  • 原文地址:https://www.cnblogs.com/iTues/p/4502333.html
Copyright © 2011-2022 走看看