进程调度模拟程序

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("\n\n");
    printf("              *********************************************             \n");
    printf("                            模拟进程调度算法\n");
    printf("              *********************************************             \n\n\n");    
    printf("                       班    级:  网络工程班\n");
    printf("                       姓    名:  张文雅\n");
    printf("                       学    号:  201306114136\n");
    printf("                       实验日期: 2015年05月17日\n\n\n\n\n\n");
    printf("                         按回车键进入演示程序");
    getchar();
    system("cls");
}
char Choice()
{
    printf("\n\n");
    printf("              *********************************************             \n");
    printf("                              进程调度演示\n");
    printf("              *********************************************             \n\n\n");    
    printf("                        1.演示最高优先数优先算法。\n");
    printf("                        2.演示轮转法算法。\n");
    printf("                        3.退出程序。\n\n\n\n");
    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:\n", 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("\n\n");
    }
    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\n\n", cases);
        printf("**** 当前正在运行的进程是:%s\n", psorted->p_name);
        psorted->p_state = 'R';
        printf("qname    state    super    ndtime    runtime\n");
        printf("%s\t%c\t%d\t%d\t%d\t\n\n", 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("**** 当前就绪状态的队列为:\n\n");
        //pt指向已经排序的队列
        pt = psorted->next;
        while (pt != NULL)
        {
            printf("qname    state    super    ndtime    runtime\n");
            printf("%s\t%c\t%d\t%d\t%d\t\n\n", 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:\n", 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("\n\n");
    }
    getchar();  //接受回车
    //processes作为头结点来存储链表
    processes = processes->next;
    int cases = 0;
    while (1)
    {
        ++cases;
        pt = processes; 
        printf("The execute number: %d\n\n", cases);
        printf("**** 当前正在运行的进程是:%s\n", pt->p_name);
        pt->p_state = 'R';
        printf("qname    state    super    ndtime    runtime\n");
        printf("%s\t%c\t%d\t%d\t%d\t\n\n", 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("**** 当前就绪状态的队列为:\n\n");
        pt = pt->next;
        while (pt != NULL)
        {
            printf("qname    state    super    ndtime    runtime\n");
            printf("%s\t%c\t%d\t%d\t%d\t\n\n", 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



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

转载于:https://www.cnblogs.com/iTues/p/4502333.html

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验一 进程调度 编写并调试一个模拟的进程调度程序,采用“短进程优先”调度算法对五个进程进行调度。以加深对进程的概念及进程调度算法的理解. 下面是采用动态优先数的调度程序,可作参考。  例题: 设计一个有 N个进程共行的进程调度程序。   进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。   每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。   进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。   进程的运行时间以时间片为单位进行计算。   每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。   就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。   如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。   每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。实验二 作业调度 一、实验目的:用高级语言编写和调试一个或多个作业调度的模拟程序,以加深对作业调度算法的理解。 二、实验内容: 1.写并调试一个单道处理系统的作业等待模拟程序。 2.作业等待算法:分别采用先来先服务(FCFS)、响应比高者优先(HRN)的调度算法。 3.由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的 CPU时限等因素。 4.每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。 5.对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间。 三、思考:比较各种算法的优缺点。 实验三 动态分区分配方式的模拟 1、实验目的:了解动态分区分配方式中的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解 2、实验内容: (1)用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程和回收过程。其中,空闲分区通过空闲分区链(表)来管理;在进行内存分配时,系统优先使用空闲区低端的空间。 (2)假设初始状态下,可用的内存空间为640KB,并有下列的请求序列: •作业1申请130KB •作业2申请60KB •作业3申请100KB •作业2释放60KB •作业4申请200KB •作业3释放100KB •作业1释放130KB •作业5申请140KB •作业6申请60KB •作业7申请50KB •作业8申请60KB 请分别采用首次适应算法和最佳适应算法进行内存的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。 3、思考:讨论各种分配算法的特点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值