码迷,mamicode.com
首页 > 系统相关 > 详细

39 进程调度实验

时间:2015-12-05 01:52:00      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

一、 实验目的

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

2.实验要求

3.设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序。

4.进程调度算法:“时间片轮转法”调度算法对N个进程进行调度。

 

二、 实验内容和要求

完成两个算法(简单时间片轮转法、多级反馈队列调度算法)的设计、编码和调试工作,完成实验报告。

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

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

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

4) 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,应把它插入就绪队列等待下一次调度。

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

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

 

三、 实验方法、步骤及结果测试

1.源程序名:1125.c

可执行程序名:1125.exe

2.原理分析及流程图

1)理解简单轮转法与多级反馈队列调度算法;

2)流程图:

技术分享

3.主要程序段及其解释:

#include<stdio.h>

#define MAX 24

typedef struct node
{
    char name[10];//作业名
    int arrivetime;//作业到达时间
    int runtime;//作业所需的运行时间
    int usetime; //已用CPU时间
    char stage; //进程的状态
    int starttime; //开始时间
    int endtime; //结束时间
    int zztime; //作业周转时间
    float zzxs; //周转系数
}JCB;

static unsigned int N=5;  //作业数
static int current=0, current1=0;  //当前时间
static unsigned int j=-1, j1=-1;
JCB job[MAX];

void Line();
void FCFS();
void getValue();
void getValue1();
void input();
void print();
void choice();
void SJF();

void getValue()
{
    unsigned int i;
    current=job[0].arrivetime;
    for(i=0; i<N; i++)   
    {
        if(job[i].stage==‘r‘ && current>=job[i].arrivetime)
        {
            if(job[i].usetime==0)
                job[i].starttime=current;
            job[i].stage=‘R‘;   //程序正在运行
            job[i].usetime++;  //CPU的运行时间加1
            current++;
        }
        if(job[i].usetime==job[i].runtime && job[i].stage==‘R‘)
        {
            j++;          //用来标记有多少进程完成了
            job[i].stage=‘F‘;
            job[i].endtime=current;
            job[i].zztime=job[i].endtime-job[i].arrivetime;
            job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
        }
        if(job[i].stage!=‘F‘)
            job[i].stage=‘r‘;  //运行完之后变回就绪态
        if(i==N-1)   //进入死循环了
            i=-1;
        if(j==N-1)
            break;
    }
}

void getValue1()
{
    unsigned int i=0, h, rest;
    current1=job[0].arrivetime;
    for(; i<N; i++)   
    {
        if(job[i].stage==‘2‘)
        {
            h=0;
            while(h<N)     //判断当前时刻的这一级是否有进程
            {
                if(job[h].stage==‘r‘ && current1>=job[h].arrivetime)
                {    
                    i=h;
                    h=N;
                }
                h++;
            }
        }
        else if(job[i].stage==‘3‘)
        {
            h=0;
            while(h<N)     //判断当前时刻的这一级是否有进程
            {
                if(job[h].stage==‘2‘)
                {    
                    i=h;
                    h=N;
                }
                h++;
            }
        }
        if(job[i].stage==‘r‘ && current1>=job[i].arrivetime)      
        {
            if(job[i].usetime==0)
                job[i].starttime=current1;
            job[i].stage=‘R‘;   //程序正在运行
            job[i].usetime++;  //CPU的运行时间加1
            current1++;
            if(job[i].usetime==job[i].runtime)
            {
                j1++;
                job[i].stage=‘F‘;
                job[i].endtime=current1;
                job[i].zztime=job[i].endtime-job[i].arrivetime;
                job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
            }
            else    //还没完成则进入下一级
                job[i].stage=‘2‘;
        }
        else if(job[i].stage==‘2‘)
        {
            job[i].stage=‘R‘;
            job[i].usetime+=2;
            current1+=2;
            if(job[i].usetime>=job[i].runtime)
            {
                j1++;
                job[i].stage=‘F‘;
                rest=job[i].usetime-job[i].runtime;
                current1=current1-rest;
                job[i].endtime=current1;
                job[i].zztime=job[i].endtime-job[i].arrivetime;
                job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
            }
            else    //还没完成则进入下一级
                job[i].stage=‘3‘;
        }
        else if(job[i].stage==‘3‘)
        {
            job[i].stage=‘R‘;
            job[i].usetime+=4;
            current1+=4;
            if(job[i].usetime>=job[i].runtime)
            {
                j1++;
                job[i].stage=‘F‘;
                rest=job[i].usetime-job[i].runtime;
                current1=current1-rest;
                job[i].endtime=current1;
                job[i].zztime=job[i].endtime-job[i].arrivetime;
                job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
            }
            else    //还没完成则在最后一级继续轮转
                job[i].stage=‘3‘;
        }
        if(i==N-1)   //进入死循环了
            i=-1;
        if(j1==N-1)
            break;
    }
}

void input()
{
    int i, jobNum, choi;
    printf("1.自选作业个数\n");
    printf("2.系统默认作业个数\n");
    printf("你的选择是:");
    scanf("%d", &choi);
    switch(choi)
    {
    case 1:
        {
            do{
                printf("\nEnter process number(作业个数应在2~24之间):");
                scanf("%d", &jobNum);   //输入作业数
                N=jobNum;
                printf("\n");
            }while(N<2 || N>24);
            break;
        }    
    case 2:
        printf("\n系统默认作业个数为5");
        break;
    }
    for(i=0; i<jobNum; i++)
    {
        printf("\njob %d name:",i+1);
        scanf(" ");
        gets(job[i].name);    //输入作业名
        printf("arrive time:");
        scanf(" %d",&job[i].arrivetime);    //输入作业达到时间
        printf("running time:");
        scanf(" %d",&job[i].runtime);    //输入作业执行时间
    }
}

void print()
{
    unsigned int i;
    printf("     name  arrivetime  runtime  starttime  endtime  zztime  zzxs\n");    
    for(i=0; i<N; i++)
    {
        printf("jod%d",i+1);
        printf("  %s\t\t%d         %d         %d         %d        %d     %.2f\n",job[i].name,job[i].arrivetime,job[i].runtime,job[i].starttime,job[i].endtime,job[i].zztime,job[i].zzxs);
    }
}
void choice()
{
    int mark;
    do{
        printf("\n\n1. 简单轮转法;\n2. 多级反馈队列调度算法;\n3. 退出.");
        printf("\nMake choice: ");
        scanf("%d", &mark);
        switch(mark)
        {
            case 1:
                FCFS();     //先来先服务
                break;
            case 2:   
                SJF();     //短作业优先
                break;    
            case 4:
                return;
            default:
                printf("\nerror!");
        }
    }while(mark!=4);
}

void Line()
{
    unsigned int a, b;
    JCB mark;
    current=0; current1=0;
    j=-1; j1=-1;
    for(a=0; a<N; a++)
    {    
        job[a].usetime=0;
        job[a].stage=‘r‘;    //就绪态
        job[a].starttime=0;
        job[a].endtime=0;
        job[a].zztime=0;
        job[a].zzxs=0;
    }
    for(a=0;a<N-1; a++)  //通过到达时间整体排序
    {
        for(b=a+1; b<N; b++)
        {
            if(job[b].arrivetime<job[a].arrivetime)
            {
                mark=job[b];
                job[b]=job[a];
                job[a]=mark;    
            }
        }
    }
}

void FCFS()
{
    Line();
    getValue();  //给每个作业内的相关参数赋值
    print();  //打印出来
}

void SJF()
{
    Line();
    getValue1();
    print();  //打印出来
}

void main()
{
    input();     //输入
    print();     //打印输出
    choice();    //选择方式
}

4.运行结果及分析

 技术分享

图4.1 提示用户输入信息

技术分享

图4.2 简单轮转法结果

技术分享

图4.3 多级反馈队列调度算法结果

 

四、 实验总结

     在前一次作业调度程序的基础上,改进成进程调度其实并不难,因为有那样的思维在里面,但是在做这次实验的过程中,首先理解简单轮转法和多级反馈跳读算法是很关键的,理解后顺着算法的思路编程,即使出现问题了,也能很快的找到是哪里的问题,并且不断地调试、改正,最后得到结果。

 

39 进程调度实验

标签:

原文地址:http://www.cnblogs.com/1994-ann/p/5020897.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!