Skip to content

Latest commit

 

History

History
36 lines (23 loc) · 3.86 KB

2014-04-02-process-life.md

File metadata and controls

36 lines (23 loc) · 3.86 KB
layout title category description tags
post
进程生命周期
进程
进程生命周期...
进程 生命周期 抢占式 多任务处理

进程并不是总是可以立即运行的,有时候进程需要等待来自外部的信号源、不受其控制的事件,例如在文本编辑器中等待键盘输入,在事件发生之前,进程都无法运行。当进程调度器运行的时候,必须知道系统中每个进程的状态。将CPU时间分配到无事可做的进程是没有意义而且也是浪费资源的。进程在各个状态之间的转换也同样重要,如果一个进程在等待来自外设的数据,那么调度器的职责是一旦数据已经到达,则需要将进程的状态由等待改为可运行(TASK_RUNNING)。

进程的运行状态可以看《进程描述符》

系统将所有进程保存在一个进程中,无论状态是运行、睡眠还是等待。但睡眠的进程会特别标记出来,调度器会知道它们无法立即运行,睡眠进程会分类到若干队列1中,因此它们可在适当的时间唤醒,例如在进程等待的外部时间已经发生时2

对于一个排队中的可运行的进程,我们可以考虑各种转换状态。如果这个进程就绪,但没有运行,因为CPU分配给了其他进程,所以这个进程的状态是等待。在调度器授予CPU时间之前,进程会一直保持该状态。在CPU分配时间之后,其状态改为『运行』。

在调度器决定从该进程收回CPU资源时,过程状态从运行改变为等待,然后循环重新开始。如果进程必须等待事件,则状态从运行改变为睡眠状态。但进程无法直接从睡眠状态变为运行。在所等待的事件发生之后,进程先时变回到『等待』状态,然后进入队列等待循环。

在程序终止,过程状态改为终止。

抢占式多任务处理

Linux进程管理的结构中还需要另外两种进程状态选项:用户态和核心态。这反应了所有CPU都至少有两种不同执行状态的事实。其中一种具有无限的权利,另一种则有各种限制。进程通常都处于用户态,只能访问自身的数据,无法感染系统中其他的应用程序,甚至也不会注意到自身之外的其他程序的存在。如果进程想要访问系统数据或功能,则必须切换到核心态。这种转换是应用程序有意调用的。

从用户态切换到核心太的另一个方法是通过中断,此时切换是自动触发的。系统调用是由应用程序有意调用的,中断则不同,其发生或多或少是不可预测的。处理中断的操作,通常与中断发生时执行的进程无关。例如外部设备向内存传输数据完毕则可能引发一个中断。例如进入系统的网络数据,也会发送中断。在Linux执行中断操作时,当前运行的进程不会察觉。

内核抢占调度模型建立了一个层次结构,用于判断哪些进程状态可以由其他状态抢占:

  1. 普通进程总是可以被抢占的,甚至由其他普通进程抢占。
  2. 如果系统处于核心态并正在处理系统调用,那么其他进程无法夺取其CPU时间,但中断可以中止系统调用。
  3. 中断可以暂停处于用户状态和核心状态的进程,中断具有最高优先级,因为中断触发后需要尽快处理。

内核抢占可以减少等待时间,因而保证『更平滑的』程序执行,但这样会增加内核复杂度,因为许多的数据需要进行并发保护,即便时在单处理器系统。

Footnotes

  1. 根据进程的状态,可能会有若干队列,当状态转换时,只要进入相应队列即可。

  2. 如等待I/O,如果没有返回则可以处于睡眠状态,一旦I/O完成,则从睡眠状态中改为可运行状态。