一、关于调度 进程调度用于多进程或者多线程并发访问资源。进程调度的需求出现在同时执行多个任务(multitasking)或者同时传输多数据流(mulplexing)。主要关心方面如下: 吞吐量:在一个整体时间内尽可能多地执行完进程,或者尽可能多地发出请求并响应。 延时:进程提交执行请求并尽早开始执行,或者请求发出之后尽早得到相应。 公平性:每个处理任务的消耗时间长度不会相差太多。 这几点有时相互矛盾,所以对于不同需求采用不同的调度算法尽量满足。 二、常见调度策略 操作系统中可以选择不同的调度算法模块,对任务进行调度,操作系统中常用的调度策略有: 1、先来先服务(FCFS) 按照请求次序进行调度。 实现简单不用对队列进行调整,但是可能因某个元素处理时间过长,出现等待超时。 2、最短作业优先(SJF) 按照作业执行的消耗时间,消耗最短时间的先执行。 需要预先估计作业执行时间,耗时较长的作业可能一直得不到执行。 3、基于优先权的调度算法(FPPS) 给作业赋予一定优先权,每次从最高优先权的元素中取出一个并执行。 4、时间片轮转(RR) 给每个作业赋予一个运行时间片,当时间片到则取下一个元素。 是对FCFS和SJF算法的折衷,不会出现超时。 5、多级队列调度(Multilevel feedback queue) 对任务进行分类,不同分类放置到不同队列中,可能会采用不同的调度算法,队列中元素视情况会在不同队列之间迁移。 选择调度策略: 以上是常见的策略,实际实现中,经常是几种方案综合实现。例如windows将多级队列,优先权队列,时间片轮转,以及先进进出方式进行综合,每种优先权任务位于不同队列,高优先权采用时间片轮转方式调度,低优先权采用先进进出方式调度。有时根据任务等待或者执行程度会调整优先权队列中元素的优先权。 三、为什么选择优先权队列? 假设我们选择优先权队列,这里给出常见的原因:


根据需求,需要对客户请求赋予一定优先级别,并且每个客户执行时间很难预先估计,采用FPPS方式实现比较容易接受。 采用一种改进方式: 1,所有客户请求都包含一定优先级别,所有请求位于一个全局队列当中。 2,当一个客户达到运行上限,则将该客户对应所有请求优先级别调整到最低(阻塞状态),相当于逻辑上将队列放置到一个阻塞队列中。 3,每次只从队列中去非阻塞客户的、最高优先级别的请求处理。 4,如果队列中没有非阻塞的客户,则等待。 5,当客户释放资源,则会将队列中所有对应该客户端的请求有限级别恢复成阻塞之前。 几个关键点: 1、优先权数越低则级别越大。(许多地方都这样实现) 2、优先权队列使用堆方式实现非常常见。(一个是排序算法复杂度低,一个是调整堆的代价小,一个是动态性强) 3、队列中任务如果处于阻塞,应当调整相应客户到低优先级,这样相当于“阻塞”了当前客户,而不影响其它同优先级客户的调度运行。(同样许多地方如此做)