进程状态

概述

进程(Process)即当前正在运行的计算机程序之实例。每个进程都有一些属性变量,这些变量决定了进程所能使用的计算机资源。进程执行过程中,会处在不同状态;正如人会处在不同的人生状态一样。

和人一样,进程也是进程它妈生的。进程从其父进程当中 fork 出来。而后,程在执行(running)的过程中,会用到一些可用的资源;这一点,和人也是一样的。如果把精力当成是一种资源,那么人睡觉就是等待精力这一资源的过程;进程也是一样,当进程执行所需的资源暂时不可用时,进程就会进入睡眠(sleeping)状态。当然,和人一样,进程也会死。一个进程可能会正常结束,相当于人的寿终正寝;也可能被杀死(kill a process)。

进程的类型

Linux 系统里有几种不同类型的进程:用户进程(User processes)、守护进程(Deamon processes)和内核进程(Kernel processes)。

用户进程

系统里大多数进程都是用户进程。用户进程由通常的用户账户启动,并在用户空间(user space)当中执行。在没有获得额外许可的情况下,通常用户进程无法对处理器进行特殊访问,或是访问启动进程的用户无权访问的文件。

守护进程

守护进程通常是后台程序,它们往往由一些持续运行的服务来管理。守护进程可以用来监听请求,而后访问某些服务。举例来说,httpd 这一守护进程监听访问网络页面的请求。守护进程也可以用来自行启动一些任务。例如,crond 这一守护进程会在预设的时间点启动计划任务。

尽管用于管理守护进程的服务通常是 root 用户启动的,但守护进程本身往往以非 root 用户启动。这种启动方式,符合 「只赋予进程运行所必须的权限」 之要求,因而能使系统免于一些攻击。举例来说,若是黑客骇入了 httpd 这一由 Apache 用户启动的守护进程,黑客仍然无法访问包括 root 用户在内的其他用户的文件,或是影响其他用户启动的守护进程。

守护进程通常由系统在启动时拉起,而后一直运行到系统关闭。当然,守护进程也可以按需启动和终止,以及让守护进程在特定的系统运行级别上执行,或是在运行过程中触发重新加载配置信息。

内核进程

内核进程仅在内核空间(kernel space)当中执行。内核进程与守护进程有些相似;它们之间主要的不同在于:内核进程对内核数据结构拥有完全的访问权限。此外,内核进程不如守护进程灵活:修改配置文件并触发重载即可修改守护进程的行为;但对于内核进程来说,修改行为则需要重新编译内核本身。

进程的三态模型

按进程在执行过程中的不同情况至少要定义三种状态:

  • 运行(running)态:进程占有处理器正在运行的状态。

    进程已获得 CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多处理机系统中,则有多个进程处于执行状态。

  • 就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行的状态。

    当进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。

  • 等待(wait)态:又称阻塞态或睡眠态,指进程不具备运行条件,正在等待某个时间完成的状态。

    也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求 I/O 而等待 I/O 完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。

02_进程状态.png

引起进程状态转换的具体原因如下:

  • 运行态→等待态:等待使用资源;如等待外设传输;等待人工干预。

  • 等待态→就绪态:资源得到满足;如外设传输结束;人工干预完成。

  • 运行态→就绪态:运行时间片到;出现有更高优先权进程。

  • 就绪态—→运行态:CPU 空闲时选择一个就绪进程。

进程的五态模型

五态模型在三态模型的基础上增加了新建态(new)和终止态(exit)。

  • 新建态:对应于进程被创建时的状态,尚未进入就绪队列。

    创建一个进程需要通过两个步骤:

    1. 为新进程分配所需要资源和建立必要的管理信息。

    2. 设置该进程为就绪态,并等待被调度执行。

  • 终止态:指进程完成任务到达正常结束点,或出现无法克服的错误而异常终止,或被操作系统及有终止权的进程所终止时所处的状态。

    处于终止态的进程不再被调度执行,下一步将被系统撤销,最终从系统中消失。终止一个进程需要两个步骤:

    1. 先等待操作系统或相关的进程进行善后处理(如抽取信息)。
  1. 然后回收占用的资源并被系统删除。

03_进程状态.png

引起进程状态转换的具体原因如下:

  • NULL→新建态:执行一个程序,创建一个子进程。

  • 新建态→就绪态:当操作系统完成了进程创建的必要操作,并且当前系统的性能和虚拟内存的容量均允许。

  • 运行态→终止态:当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结。

  • 运行态→就绪态:运行时间片到;出现有更高优先权进程。

  • 运行态→等待态:等待使用资源;如等待外设传输;等待人工干预。

  • 就绪态→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。

  • 等待态→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。

  • 终止态→NULL:完成善后操作。

进程的七态模型

三态模型和五态模型都是假设所有进程都在内存中的事实上有序不断的创建进程,当系统资源尤其是内存资源已经不能满足进程运行的要求时,必须把某些进程挂起(suspend),对换到磁盘对换区中,释放它占有的某些资源,暂时不参与低级调度。起到平滑系统操作负荷的目的。

引起进程挂起的原因是多样的,主要有:

  1. 终端用户的请求。当终端用户在自己的程序运行期间发现有可疑问题时,希望暂停使自己的程序静止下来。亦即,使正在执行的进程暂停执行;若此时用户进程正处于就绪状态而未执行,则该进程暂不接受调度,以便用户研究其执行情况或对程序进行修改。我们把这种静止状态成为 “挂起状态”。

  2. 父进程的请求。有时父进程希望挂起自己的某个子进程,以便考察和修改子进程,或者协调各子进程间的活动。

  3. 负荷调节的需要。当实时系统中的工作负荷较重,已可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起,以保证系统能正常运行。

  4. 操作系统的需要。操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。

  5. 对换的需要。为了缓和内存紧张的情况,将内存中处于阻塞状态的进程换至外存上。

七态模型在五态模型的基础上增加了挂起就绪态(ready suspend)和挂起等待态(blocked suspend)。

  • 挂起就绪态:进程具备运行条件,但目前在外存中,只有它被对换到内存才能被调度执行。

  • 挂起等待态:表明进程正在等待某一个事件发生且在外存中。

04_进程状态.png

引起进程状态转换的具体原因如下:

  • 等待态→挂起等待态:操作系统根据当前资源状况和性能要求,可以决定把等待态进程对换出去成为挂起等待态。

  • 挂起等待态→挂起就绪态:引起进程等待的事件发生之后,相应的挂起等待态进程将转换为挂起就绪态

  • 挂起就绪态→就绪态:当内存中没有就绪态进程,或者挂起就绪态进程具有比就绪态进程更高的优先级,系统将把挂起就绪态进程转换成就绪态。

  • 就绪态→挂起就绪态:操作系统根据当前资源状况和性能要求,也可以决定把就绪态进程对换出去成为挂起就绪态。

  • 挂起等待态→等待态:当一个进程等待一个事件时,原则上不需要把它调入内存。但是在下面一种情况下,这一状态变化是可能的。当一个进程退出后,主存已经有了一大块自由空间,而某个挂起等待态进程具有较高的优先级并且操作系统已经得知导致它阻塞的事件即将结束,此时便发生了这一状态变化。

  • 运行态→挂起就绪态:当一个具有较高优先级的挂起等待态进程的等待事件结束后,它需要抢占 CPU,而此时主存空间不够,从而可能导致正在运行的进程转化为挂起就绪态。另外处于运行态的进程也可以自己挂起自己。

  • 新建态→挂起就绪态:考虑到系统当前资源状况和性能要求,可以决定新建的进程将被对换出去成为挂起就绪态。

挂起进程等同于不在内存中的进程,因此挂起进程将不参与低级调度直到它们被调换进内存。挂起进程具有如下特征:

  • 该进程不能立即被执行

  • 挂起进程可能会等待一个事件,但所等待的事件是独立于挂起条件的,事件结束并不能导致进程具备执行条件。 (等待事件结束后进程变为挂起就绪态)

  • 进程进入挂起状态是由于操作系统、父进程或进程本身阻止它的运行。

  • 结束进程挂起状态的命令只能通过操作系统或父进程发出。