《深入理解linux内核》学习 — 进程调度

调度不陌生,但很重要

传统Unix操作系统的调度算法必须实现几个互相冲突的目标:

  1. 进程响应时间尽可能快
  2. 后台作业的吞吐量尽可能高
  3. 尽可能避免进程的饥饿现象
  4. 低优先级和高优先级进程需要尽可能调和

决定什么时候以怎样的方式选择一个新进程运行的这组规则就是所谓的调度策略。

Linux的调度基于分时技术:多个进程以”时间多路复用“方式运行,CPU的时间被分成片,给每个可运行的进程分配一片,单处理器在任何给定的时刻只能运行一个进程,分时依赖于定制终端,不需要在程序中插入额外代码。

调度策略也是根据进程的优先级对他们进行分类,看过本书第三章应该就对此了解了。

在Linux中,进程的优先级是动态的,比如,在较长的时间间隔内没有使用CPU的进程,就可以动态的提高它的优先级。

传统意义上把进程分为I/O受限(有大量IO)或CPU受限(需要大量CPU执行时间)两类,但另一种分类法把进程分为三类:

调度算法

策略从提上还是比较经典的,从三个角度考虑即可:

  1. 优先级
  2. 时间片
  3. 能否抢占

正常情况下,如果进程都一视同仁,那必然是轮询调度,但考虑上述三个因素就需要有不一样的策略。

但是及时具有较高静态优先级的普通进程获得了较大的CPU时间片(通常优先级越高,时间片越大),也不应使静态优先级较低的进程无法运行。为了避免进程饥饿,当一个进程都用完了时间片,它应该被没用完时间片的低优先级进程取代。为了实现这种机制,调度程序位置两个不相交的可运行进程集合:

  1. 活动进程

这些进程还没用完时间片,允许运行

  1. 过期进程

这些可运行进程已经用完了时间片,被禁止运行,直到所有活动进程都过期

但这里有个前提,是普通进程,交互式进程和实时进程策略有所不同。

调度程序所使用的数据结构

runqueue是Linux2.6中调度程序最重要的数据结构,每个CPU都有自己的运行队列,每个进程只属于一个运行队列,只能在拥有该队列的CPU上执行,但运行进程可以从一个队列迁移到别的队列。

多处理器系统中运行队列的平衡

Linux一直采用多处理器模型,内核不应该对一个CPU有任何偏袒,让一个CPU一致工作,让其余CPU较为空闲是不合理的。

这里采用了调度域的思想,调度与表示一个CPU集合,采用分层的组织形式,一个调度与有很多组,工作量的平衡总是在调度与的组织间完成。

留下评论