zoukankan      html  css  js  c++  java
  • czxt

    实验三 进程调度模拟程序

    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). (**)在进行模拟调度过程可以创建(增加)进程,其到达时间为进程输入的时间。

    0.

    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.    实验原理及核心算法参考程序段

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

    //优先级调度算法
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #define getpch(type) (type*)malloc(sizeof(type))
    #define NULL 0
    struct pcb
    {
    /* 定义进程控制块PCB */
    char name[10];
    char state;
    int super;
    int ntime;
    int rtime;
    struct pcb* link;
    }*ready=NULL,*p;
    typedef struct pcb PCB;

    int num=0;

    void sort() /* 建立对进程进行优先级排列函数*/
    {
    PCB *first, *second;
    int insert=0;
    if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/
    {
    p->link=ready;
    ready=p;
    }
    else /* 进程比较优先级,插入适当的位置中*/
    {
    first=ready;
    second=first->link;
    while(second!=NULL)
    {
    if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/
    {
    /*插入到当前进程前面*/
    p->link=second;
    first->link=p;
    second=NULL;
    insert=1;
    }
    else /* 插入进程优先数最低,则插入到队尾*/
    {
    first=first->link;
    second=second->link;
    }
    }
    if(insert==0) first->link=p;
    }
    }

    int space()
    {
    int l=0;
    PCB* pr=ready;
    while(pr!=NULL)
    {
    l++;
    pr=pr->link;
    }
    return(l);
    }

    void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
    {
    printf(" 进程名 状态 优先数 需要运行时间 已经运行时间 ");
    printf(" %s",pr->name);
    printf(" %c",pr->state);
    printf(" %d",pr->super);
    printf(" %d",pr->ntime);
    printf(" %d",pr->rtime);
    printf(" ");
    }


    void check() /* 建立进程查看函数 */
    {
    PCB* pr;
    printf(" **** 当前正在运行的进程是: "); /*显示当前运行进程*/
    disp(p);
    pr=ready;
    printf(" **** 当前就绪队列状态为: "); /*显示就绪队列状态*/
    while(pr!=NULL)
    {
    disp(pr);
    pr=pr->link;
    }
    }

    void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
    {
    printf(" 进程 [%s] 已完成. ",p->name);
    free(p);
    }

    void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
    {
    (p->rtime)++;
    if(p->rtime==p->ntime)
    destroy(); /* 调用destroy函数*/
    else
    {
    if(p->super>0)
    (p->super)--;
    p->state='W';
    sort(); /*调用sort函数*/
    }
    }

    //手动输入模拟函数
    void manuallyEnter(){

    int i;
    system("cls"); /*清屏*/
    printf(" 请输入进程数: ");
    scanf("%d",&num);
    printf(" ");
    for(i=1;i<=num;i++)
    {
    printf(" 第%d个进程: ",i);
    p=getpch(PCB);
    printf(" 输入进程名:");
    scanf("%s",p->name);
    printf(" 输入进程优先数:");
    scanf("%d",&p->super);
    printf(" 输入进程运行时间:");
    scanf("%d",&p->ntime);
    printf(" ");
    p->rtime=0;
    p->state='W';
    p->link=NULL;
    sort(); /* 调用sort函数*/
    }

    }


    //读取文件
    void readFile()
    {
    //读取文件
    FILE *fp = fopen("pcb.txt","r");
    if(fp == NULL)
    {
    printf("File open error! ");
    exit(0);
    }
    while(!feof(fp)&&fgetc(fp)!=EOF)
    {
    fseek(fp,-1L,SEEK_CUR);
    fscanf(fp,"%s%d%d",&p->name,&p->super,&p->ntime);
    num++;
    }
    fclose(fp);

    }

    //选择数据的获取方式
    void dataAccess()
    {
    int k;
    printf(" ************************************** ");
    printf(" 1.调用文本写入数据 ");
    printf(" 2.调用手动输入模拟数据 ");
    printf(" ************************************** ");
    printf(" 请选择菜单项: ");
    scanf("%d",&k);
    switch(k){
    case 1:
    readFile();
    break;
    case 2:
    manuallyEnter();
    break;
    default:
    printf(" **请输出1或者2进行选择");
    dataAccess();
    break;
    }
    }

    void output()
    {
    int len,h=0;
    char ch;
    len=space();
    while((len!=0)&&(ready!=NULL))
    {
    ch=getchar();
    h++;
    printf(" ----------------------------------------------------- ");
    printf(" 现在是第%d次运行: ",h);
    p=ready;
    ready=p->link;
    p->link=NULL;
    p->state='R';
    check();
    running();
    printf(" 按任意键继续...... ");
    }
    }

    int main() /*主函数*/
    {
    dataAccess();
    output();
    printf(" 进程已经完成. ");
    }

  • 相关阅读:
    fn project 试用之后的几个问题的解答
    fn project 扩展
    fn project 生产环境使用
    fn project 对象模型
    fn project AWS Lambda 格式 functions
    fn project 打包Function
    fn project Function files 说明
    fn project hot functions 说明
    fn project k8s 集成
    fn project 私有镜像发布
  • 原文地址:https://www.cnblogs.com/zhenzengwen/p/5487735.html
Copyright © 2011-2022 走看看