异想天开

What's the true meaning of light, Could you tell me why

进程状态

日期:2015-02-04 15:44:27
  
最后更新日期:2015-02-06 10:36:18
【笔记】
进程状态粗略可以分为以下几种:
[code lang="cpp"]
running 运行状态
trace 执行strace或gdb命令trace进程
sleep 睡眠状态
dead 终止状态
zombie 僵尸状态
[/code]
查阅内核源码交叉引用,见参考1。这里以2.6.30版本为例,其它版本或新增了另外的状态。进程的状态也就是task_struct里面的state字段。/include/linux/sched.h文件列举了内存定义进程的宏:
[code lang="cpp"]
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8
/* in tsk->exit_state */
#define EXIT_ZOMBIE 16
#define EXIT_DEAD 32
/* in tsk->state again */
#define TASK_DEAD 64
#define TASK_WAKEKILL 128
[/code]
这些bit(位移信息)还与另外一个数组的索引对应,该数字定义在/fs/proc/array.c
[code lang="cpp"]
static const char *task_state_array[] = {
136 "R (running)", /* 0 */
137 "S (sleeping)", /* 1 */
138 "D (disk sleep)", /* 2 */
139 "T (stopped)", /* 4 */
140 "T (tracing stop)", /* 8 */
141 "Z (zombie)", /* 16 */
142 "X (dead)" /* 32 */
143 };
[/code]
可以看出TASK_UNINTERRUPTIBLE(不可中断的睡眠状态)对应的为"D (disk sleep)",__TASK_STOPPED为暂停状态。暂停状态是怎么引起的?向进程发送SIGSTOP信号,那么进程就会暂停,发送SIGCONT信号,进程就会继续执行。测试时,暂停时,还是可以处理其他信号的。
[code lang="cpp"]
kill -19 {pid} //发送 SIGSTOP 信号
kill -18 {pid} //发送 SIGCONT 信号
[/code]
一幅进程的状态变迁图如下:
states 说明:
1.D(Disk Sleeping)睡眠状态与S(Sleeping)状态是有区别的,D(Disk Sleeping)是不可中断的,意味着不处理信号,stop(暂停)状态和S(Sleeping)状态还可以继续处理信号。
2.Z(zombie)状态是父进程没有waitpid,子进程就成了僵死进程。这里看作所有进程会先进入僵死状态,等待父进程回收,若父进程没有回收,则一直是僵死状态。
3.进程状态随着内核也在不断适应新问题而发展。
某次与进程状态相关的问题分析:
top命令时,发现180来个僵尸进程。僵尸进程是对外提供服务的程序,启动脚本大概如下:
[code lang="cpp"]
./exe_bin_file &
tail -f ./exe_log_file
[/code]
该脚本在crond监控里面启动,由于tail是用-f参数执行的,tail命令不会退出,同时shell(父进程)执行tail是阻塞式的执行,故shell(父进程)不会退出。shell(父进程)中用加了&启动的进程,shell不会对其waitpid。这样exe_bin_file退出后就会成为僵尸进程,恰好exe_bin_file由于有个bug不停的崩溃,导致形成了180个僵尸进程。
参考:
源码交叉引用