Linux进程状态分析

最近在看APUE过程中,遇到了一个有关于进程的“僵死进程”的状态。既然遇到了进程状态的问题,索性就查了查《Linux内核设计与实现》,里面给出了5种状态,分别是“TASK_RUNNING”、“TASK_INTERRUPTIBLE”、“TASK_UNINTERRUPTIBLE”、“__TASK_STOPPED”、“__TASK_TRACED”,但这5种状态中偏偏没有“僵死”这么一个状态,这到底是怎么一回事呢?

其实这个问题很好解决。我获取有关于进程状态信息的命令是什么?ps,没错。有关于进程状态的信息都来自于ps命令,那是否是ps的输出在误导我呢?

答案是肯定的,ps的输出确实在一定程度上误导了我,先来看看ps命令的输出,ps有关于进程状态的输出共有7中,分别是:

D    uninterruptible sleep (usually IO) //不可中断睡眠
R    running or runnable (on run queue)  //正在执行或可执行
S    interruptible sleep (waiting for an event to complete) //可中断睡眠状态
T    stopped, either by a job control signal or because it is being traced //停止或追踪状态
W    paging (not valid since the 2.6.xx kernel) //换页,但2.6之后内核已不再可用
X    dead (should never be seen) //死亡,但应该永远也看不到
Z    defunct ("zombie") process, terminated but not reaped by its parent //僵死状态(已经终止但还没有被父进程回收)

以上内容来自于man ps中“PROCESS STATE CODES”一节。 

好了,以上就是ps的输出了,那么源码中是如何定义的呢?让我们来看看源码中是如何定义的,相关定义位于./include/linux/sched.h中:

#define TASK_RUNNING		0
#define TASK_INTERRUPTIBLE	1
#define TASK_UNINTERRUPTIBLE	2
#define __TASK_STOPPED		4 进程的执行被暂停,当进程接收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU信号后,进入暂停状态
#define __TASK_TRACED		8
/* in tsk->exit_state */
#define EXIT_DEAD		16 
#define EXIT_ZOMBIE		32 
#define EXIT_TRACE		(EXIT_ZOMBIE | EXIT_DEAD)
/* in tsk->state again */
#define TASK_DEAD		64
#define TASK_WAKEKILL		128
#define TASK_WAKING		256
#define TASK_PARKED		512
#define TASK_STATE_MAX		1024

好了真相大白了,原来ps的输出与源码中的定义还不是完全一致的,这也就造成了我通过ps输出的结果与《Linux内核设计与实现》中写的内容不同。

既然是谈“僵死状态”,那就详细研究一下这个状态。“EXIT_ZOMBIE”状态表示进程的执行被终止(注意是已经终止了,而不是暂停,进程暂停了还能恢复),但是父进程还没有发布wait4()或waitpid()系统调用来返回有关死亡进程的信息。“EXIT_ZOMBIE”与“EXIT_DEAD”状态即可以存放在进程描述符的state字段中,也可以存放在exit_state字段中。

至此我们已经了解了ps的输出与内核源码的定义,让我们来看看他们之间的对应关系。

ps命令输出 内核源码定义
D    uninterruptible sleep (usually IO) TASK_UNINTERRUPTIBLE
R    running or runnable (on run queue) TASK_RUNNING
S    interruptible sleep (waiting for an event to complete) TASK_INTERRUPTIBLE
T    stopped, either by a job control signal or because it is being traced __TASK_STOPPED or __TASK_TRACED
W    paging (not valid since the 2.6.xx kernel)  
X    dead (should never be seen) 可能是EXIT_DEAD或TASK_DEAD,这一点还无法确认
Z    defunct ("zombie") process, terminated but not reaped by its parent EXIT_ZOMBIE or EXIT_TRACE


最后让我们看看各进程状态之间转化关系图。这幅图是我在网上的图的基础上稍加改变得到的。

Linux进程状态分析_第1张图片

你可能感兴趣的:(动静结合看内核)