Linux进程状态

 

参考:http://blog.csdn.net/gatieme/article/details/51383272linux

进程是处于执行期的程序以及它所管理的资源(如打开的文件、挂起的信号、进程状态、地址空间等等)的总称。注意,程序并非进程,实际上两个或多个进程不只有可能执行同一程序,并且还有可能共享地址空间等资源。程序员

Linux内核经过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的全部信息。它定义在include/linux/sched.h文件中。函数

谈到task_struct结构体,是linux内核源码中最复杂的一个结构体了,成员之多,占用内存之大。spa

下面来慢慢介绍这些复杂成员.net

进程状态

5个互斥状态

state域可以取5个互为排斥的值(通俗一点就是这五个值任意两个不能一块儿使用,只能单独使用)。系统中的每一个进程都必然处于以上所列进程状态中的一种。debug

状态调试

描述code

TASK_RUNNINGblog

表示进程要么正在执行,要么正要准备执行(已经就绪),正在等待cpu时间片的调度队列

TASK_INTERRUPTIBLE

进程由于等待一些条件而被挂起(阻塞)而所处的状态。这些条件主要包括:硬中断、资源、一些信号……,一旦等待的条件成立,进程就会从该状态(阻塞)迅速转化成为就绪状态TASK_RUNNING

TASK_UNINTERRUPTIBLE

意义与TASK_INTERRUPTIBLE相似,除了不能经过接受一个信号来唤醒之外,对于处于TASK_UNINTERRUPIBLE状态的进程,哪怕咱们传递一个信号或者有一个外部中断都不能唤醒他们。只有它所等待的资源可用的时候,他才会被唤醒。这个标志不多用,可是并不表明没有任何用处,其实他的做用很是大,特别是对于驱动刺探相关的硬件过程很重要,这个刺探过程不能被一些其余的东西给中断,不然就会让进城进入不可预测的状态

TASK_STOPPED

进程被中止执行,当进程接收到SIGSTOP、SIGTTIN、SIGTSTP或者SIGTTOU信号以后就会进入该

TASK_TRACED

表示进程被debugger等进程监视,进程执行被调试程序所中止,当一个进程被另外的进程所监视,每个信号都会让进城进入该状态

2个终止状态

其实还有两个附加的进程状态既能够被添加到state域中,又能够被添加到exit_state域中。只有当进程终止的时候,才会达到这两种状态.

/* task state */

int exit_state;

int exit_code, exit_signal;

状态

描述

EXIT_ZOMBIE

进程的执行被终止,可是其父进程尚未使用wait()等系统调用来获知它的终止信息,此时进程

EXIT_DEAD

进程的最终状态

而int exit_code, exit_signal;咱们会在后面进程介绍

3.新增睡眠状态

TASK_KILLABLE:Linux 中的新进程状态

如前所述,进程状态 TASK_UNINTERRUPTIBLE 和 TASK_INTERRUPTIBLE 都是睡眠状态。如今,咱们来看看内核如何将进程置为睡眠状态。

Linux 内核提供了两种方法将进程置为睡眠状态。

将进程置为睡眠状态的普通方法是将进程状态设置为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE 并调用调度程序的 schedule() 函数。这样会将进程从 CPU 运行队列中移除。

•若是进程处于可中断模式的睡眠状态(经过将其状态设置为 TASK_INTERRUPTIBLE),那么能够经过显式的唤醒呼叫(wakeup_process())或须要处理的信号来唤醒它。

•可是,若是进程处于非可中断模式的睡眠状态(经过将其状态设置为 TASK_UNINTERRUPTIBLE),那么只能经过显式的唤醒呼叫将其唤醒。除非万不得已,不然咱们建议您将进程置为可中断睡眠模式,而不是不可中断睡眠模式(好比说在设备 I/O 期间,处理信号很是困难时)。

当处于可中断睡眠模式的任务接收到信号时,它须要处理该信号(除非它已被屏弊),离开以前正在处理的任务(此处须要清除代码),并将 -EINTR 返回给用户空间。再一次,检查这些返回代码和采起适当操做的工做将由程序员完成。

所以,懒惰的程序员可能比较喜欢将进程置为不可中断模式的睡眠状态,由于信号不会唤醒这类任务。

但须要注意的一种状况是,对不可中断睡眠模式的进程的唤醒呼叫可能会因为某些缘由不会发生,这会使进程没法被终止,从而最终引起问题,由于唯一的解决方法就是重启系统。一方面,您须要考虑一些细节,由于不这样作会在内核端和用户端引入 bug。另外一方面,您可能会生成永远不会中止的进程(被阻塞且没法终止的进程)。

如今,咱们在内核中实现了一种新的睡眠方法

Linux Kernel 2.6.25 引入了一种新的进程睡眠状态,

状态         描述

TASK_KILLABLE         当进程处于这种能够终止的新睡眠状态中,它的运行原理相似于 TASK_UNINTERRUPTIBLE,只不过能够响应致命信号

它定义以下:

#define TASK_WAKEKILL           128 /** wake on signals that are deadly **/

 

/* Convenience macros for the sake of set_task_state */

#define TASK_KILLABLE           (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)

#define TASK_STOPPED            (TASK_WAKEKILL | __TASK_STOPPED)

#define TASK_TRACED             (TASK_WAKEKILL | __TASK_TRACED)

换句话说,TASK_UNINTERRUPTIBLE + TASK_WAKEKILL = TASK_KILLABLE。

而TASK_WAKEKILL 用于在接收到致命信号时唤醒进程

新的睡眠状态容许 TASK_UNINTERRUPTIBLE 响应致命信号

进程状态的切换过程和缘由大体以下图:

 

相关文章
相关标签/搜索