操作系统--进程管理(二)

进程调度

多道程序设计的目的是 无论何时都有进程在运行, 从而使CPU利用率达到最大化。
分时系统的目的是在进程间频繁切换 CPU, 以便用户在程序运行时能与其交互。
单处理器系统只能有一个运行进程。如果存在多个进程,需要等待CPU空闲并重新调度。

4.2.1 调度队列

进程进入系统时, 会被加到 作业队列中。 该队列包括系统中的所有进程。 驻留在内存中就绪 的等待运行的进程保存在 就绪队列 表上。该队列通常用链表形式存储,其头节点包括指向链表的第一个和最后一个 PCB块上的指针。 可以为每个 PCB增加一个指针域来指向 就绪队列的下一个PCB。
操作系统也有其他队列。 当给进程分配了CPU后, 它开始执行并最终完成、退出, 或被中断, 或等待 特定的事件发生, 如I/O请求的完成。 对于I/O请求的情况, 这个请求可能发现 专用磁带驱动器或 共享设备(如磁盘)。 由于系统由许多进程, 磁盘可能会忙于其他进程的 I/O 请求, 因此该进程可能需要等待 磁盘。等待 待定I/O设备的 进程列表称为 设备列表。 每个设备都有自己的设备列表。

操作系统--进程管理(二)
就绪队列和各种I/O设备队列
进程调度的常用表示方法是队列图, 如下图4.5 所示。 每个长方形表示一个队列。 有两种队列:就绪队列和一组设备队列。 圆形表示为队列服务的资源, 箭头表示系统内进程的流向。

新进程开始处于就绪队列。 它在就绪队列中等待知道被 选中执行(或分派)。当进程分配到 CPU并执行时, 有几种事情可能发生:

  • 进程可能发出一个I/O请求, 并被放到I/O队列中。
  • 进程可能创建一个新的子进程,并等待其结束。
  • 进程可能会由于中断而被强行移除CPU, 并被放回到就绪队列。
    对于前两种 情况, 进程最终从等待状态切换 到就绪状态, 并放回到 就绪队列。 进程继续这一循环知道他终止, 到时 它将从所有队列中被移除, 其PCB 和资源将得以重新分配。
    操作系统--进程管理(二)
    图4.5 表示进程调度的队列图

4.2.3 调度程序

进程在其生命周期中会在各种调度队列之间迁移。 操作系统为了调度的目的, 必须按某种方式从这些队列中 选择进程。 进程选择是由相应的 调度程序(scheduler)来完成的。
对于批处理系统, 通常会提交很多进程, 不能够马上都执行。 这些进程被放到大容量存储设备上(通常为磁盘)的缓冲池中, 保存在那里以便后来执行。长期调度程序作业调度程序从该池中选择进程, 并将它们装入内存以执行。 短期调度程序CPU调度程序 从就绪可执行的进程中选择今晨个,并未其中之一分配CPU。
这两种调度程序的主要差别是它们执行的频率。 短期调度程序必须频繁地为CPU选择新进程。进程可能执行数毫秒(ms)就会等待一个I
/O 请求。 短期调度程序通常每100ms 至少执行一次。 由于每次执行之间的时间较短, 短期调度程序必须要快。 如果需要10ms来确定执行一个运行100ms 的进程。那么10/(100+10) = 9% 的CPU时间会仅仅用于(或浪费在) 调度工作上。
另一方面,长期调度程序执行得并不频繁。 在系统内新进程的创建之间可能有数分钟间隔。 长期调度程序控制 多道程序设计的程度,即内存 中的进程数量。 如果多道程序设计的程度稳定, 那么创建进程的平均速度必须等于进程离开系统的平均速度。 因此,长期调度程序可能需要在进程离开系统是才能被唤起。 由于每次执行之间的较长时间间隔, 长期调度程序能使用更多的时间来选择执行进程。

长期调度程序必须仔细选择。通常, 绝大多数进程可分为: I/O 为主或CPU位主。 I/O位主的进程(I/O-bound process)在执行I/O方面比执行计算要花费更多的时间。 另一方面, CPU为主的进程(CPU-bound process)很少产生I/O请求, 与I/O请求相比更多的时间集中在执行计算上。 因此, 长期调度程序应该选择 一个合理的I/O为主进程和cpu调度为主进程的进程组合。 如果所有进程是CPU为主的, 那么I/O等待队列将几乎总为空, 从而设备并没有得到使用, 因而系统会不平衡。 为了得到最好性能,系统需要一个合理的组合。

对于有些系统,长期调度程序可能没有货很小。例如, 分时系统如 UNIX通常没有长期调度程序, 只是简单地将所有新进程放在内存中,以供短期调度程序使用。 这些系统的稳定性依赖物理限制(如可用的终端数)或自然人用户的自我调整特性。 如果系统性能下降到令人难以接受的程度,则用户会退出。

4.2.3 上下文切换

CPU 切换到另一个进程需要保存原来进程的状态并装入新进程的保存状态。这一任务称为 上下文切换 (context switch)。进程关联 是由进程的PCB表示的,它包括CPU寄存器的值,进程状态和 内存管理信息等 。
当发生上下文切换时, 内核会将旧进程的关联状态保存到 其PCB中, 然后装入调度要执行的新进程的已保存的关联状态。上下文切换时间是 额外开销, 因为切换时系统并不能做什么有用的 工作,上下文切换速度因机器而不同, 它依赖于内存速度,必须被赋值的寄存器的数量、是否有特殊指令(如装入或保存所有寄存器的单个指令)。典型速度位1微秒 到 1000 微秒。

上下文切换时间和硬件支持密切相关。 例如, 有的处理器提供了多个寄存器组, 上下文切换 只需要简单地改变当前寄存器组的指针。 当然, 如果活动进程超过了寄存器组数量, 那么系统需要像以前一样在寄存器与内存之间进行数据复制。 而且, 操作系统越复杂, 上下文切换所需要做的工作越多。