天天看点

操作系统--进程调度算法

一、要求

(1)先来先服务算法,短进程优先算法,高优先级优先算法,时间片轮转调度算法;

(2)有录入界面,动态录入进程个数,进程标识符,进入时间,服务时间,优先级,系统时间片长短等信息;

(3)有算法选择界面,能够选择不同的调度算法;

(4)有输出界面,输出不同调度算法下诸进程的进程标识符,进入时间,服务时间,开始时间,完成时间,周转时间,带权周转时间及一组进程的平均周转时间及平均带权周转时间。

二、原理

定义一个进程控制块PCB,包含进程标识符,进入时间,服务时间,开始时间,完成时间,周转时间,带权周转时间等一系列将会用到的数据成员,再利用构造函数对进程标识符,进入时间,服务时间,优先级赋值。

用courseQueue类来定义不同算法调度下队列的变化(即进程进出队情况),enterQueue()进程进队的方法,在先来先服务算法,短作业优先算法和高优先级优先算法中使用outQueue()出队方法,在时间片轮转算法中使用outQueueRoundRubin(double sliceTime)出队方法。

ContrastArrivetime类对到达时间由先到后进行排序,ContrastPriority类对不同优先级的进程进行排序,ContrastServetime类对服务时间由短到长排序。

Course类中的init()方法动态录入进程个数及各进程信息,Select()方法中包含算法选择页面,用switch ,case语句进行不同算法的选择。

三、主要内容及步骤

1、 算法流程

(1)主要函数:

  • Course.Init():对进程个数及各进程的信息进行初始化;
  • Course.Select():包含算法选择目录,输入不同序号,调用不同算法;
  • courseQueue.enterQueue():使到达进程入队;
  • courseQueue.outQueue():基本的出队操作;
  • courseQueue.outQueueRR():时间片轮转算法下的出队操作。

(2)核心算法及解析:

public void enterQueue()//进程入队函数
{
    while (nowIndex < storage.size()) {
        if (storage.get(nowIndex).arriveTime <= nowTime)//入队进程到达时间必须小于等于当前时间
        {
            memory.add(storage.get(nowIndex));//放入内存
            nowIndex++;                      //下标自加
        }
        else
        {
            break;
        }
    }
}
           

解析:

进程入队函数,所有算法都用storage(存放所有进程),memory(存放已经准备就绪的进程),result(存放结果)对进程进行操作。判断当前满足条件的进程将其放入内存memory。

public void outQueue()                         //普通出队函数
{
    nowProess = memory.removeFirst();          //弹出队首元素
    getData();                            //计算完成时间等数值
    result.add(nowProess);                  //加入result结果集
}
           

解析:普通出队函数,进程要出队,即进程已经执行完毕。首先弹出队首元素,再调用getData()函数进行所需数据的计算,将计算结果加入result结果集中。

public void outQueueRR(double sliceTime)    //时间片轮转出队函数
{
    nowProess = memory.removeFirst();       //弹出队首元素
    nowProess.outQueueTime++;
    if(nowProess.outQueueTime == 1)   //判断进程是否为第一层轮转
    {
        nowProess.beginTime = nowTime;          //记录开始时间
    }
    nowTime += sliceTime;             //每次出队时使用一个时间片
    nowProess.clock+=sliceTime; //更新当前出队列的进程已服务时间
    if(nowProess.clock>=nowProess.serviceTime)
    {
        nowProess.finishTime=nowTime;     //计算进程的完成时间
        nowProess.roundTime = nowProess.finishTime - nowProess.arriveTime;                //计算进程的周转时间
        nowProess.turnRoundTime = (double)nowProess.roundTime / nowProess.serviceTime;    //计算进程的平均周转时间
        result.add(nowProess);    //加入result集
        enterQueue();
    }
    else {
        enterQueue();                   //已到达的进程先入队
        memory.addLast(nowProess);    //上一轮弹出的进程进入队尾
    }
}
           

解析:时间片轮转出队函数,首先弹出队首元素并且判断是否为第一次轮转,并且要判断已服务时间clock和服务时间serviceTime ,若大于的话,该进程已经执行完毕,该进程加入结果集,再进行下一次的轮转。

(3)流程图:

操作系统--进程调度算法

2. 运行结果分析

进程录入界面:

操作系统--进程调度算法

调度算法选择界面:

操作系统--进程调度算法

(4)不同算法选择下的结果及分析:

1)先来先服务算法下的结果及分析:

操作系统--进程调度算法

分析:0时刻A进程进入内存,开始执行,2时刻B进程到达,3时刻C进程到达,均阻塞于外存等待队列,4时刻A进程执行完毕。按照先来先服务算法,将B进程调入内存开始执行。5时刻D进程到达,阻塞于外存等待队列,7时刻B进程执行完毕。按照先来先服务算法,将C进程调入内存开始执行,12时刻C执行完毕,将D调入内存,14时刻D执行完毕。

2)短作业优先下的算法结果及分析:

操作系统--进程调度算法

分析:0时刻A进程进入内存开始运行,2时刻B进程到达,由于A进程占有CPU,所以B进程阻塞于外存等待队列,3时刻C进程到达,由于A进程占有CPU,所以C进程也阻塞于外存等待队列,4时刻时A进程运行完毕。此时,由于B进程的服务时间为3,C进程的服务时间为5,按照短作业优先算法,B进程调入内存开始运行,5时刻D进程到达,由于B进程占有CPU,所以D进程阻塞于外存等待队列。7时刻时,B进程执行完毕,由于D进程的服务时间为2,C进程的服务时间为5,按照短作业优先算法,D进程调入内存开始执行。9时刻D进程执行完毕,C进程调入内存开始执行,14时刻C进程执行完毕。

3)高优先级优先算法下的结果及分析

操作系统--进程调度算法

分析:0时刻A进程开始运行。2时刻B进程到达,3时刻C进程到达,均阻塞于外存等待队列,4时刻A进程执行完毕。根据高优先级优先算法,C的优先级为4大于B的优先级3,所以C调入内存开始运行。5时刻D到达,阻塞于外存等待队列。9时刻C执行完毕。由于D的优先级大于B,所以D调入内存开始运行,11时刻D执行完毕,B调入内存,14时刻B执行完毕。

4)时间片轮转下的算法结果及分析:

操作系统--进程调度算法

分析:由于五个进程的进入时间都为0,即几乎同时到达,时间片为2。0时刻A进程开始运行,系统为A,B,C,D,E各进程分配时间片,分配完后为10时刻。由于2时刻A执行完毕,所以第二轮分配时间片时不考虑A。10时刻时B进程执行,12时刻B执行完毕,系统为B,C,D,E分配时间片,分配完后为18时刻。以此类推可得到时间片轮转算法下的开始时间及完成时间。

继续阅读