Linux的进程状态

=Start=

缘由:

补充一些基础的Linux系统知识。

正文:

参考解答:
进程状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面的状态在 fs/proc/array.c 文件里定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)",      /* 0 */正在运行 或 可运行(在运行队列排队中)
"S (sleeping)",     /* 1 */可中断睡眠(休眠中,受阻,在等待某个条件的形成或接收到信号)
"D (disk sleep)",   /* 2 */不可中断睡眠(通常是在IO操作),收到信号不唤醒和不可运行,进程必须等待直到有中断发生
"T (stopped)",      /* 4 */暂停状态,进程收到 SIGSTOP, SIGSTP, SIGTIN, SIGTOU 信号后停止运行
"t (tracing stop)", /* 8 */跟踪状态,指的是进程暂停下来,等待跟踪它的进程对它进行操作
"X (dead)",         /* 16 */退出状态,进程即将被销毁
"Z (zombie)",       /* 32 */退出状态,进程成为僵尸进程
};

运行状态(running)并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

睡眠状态(sleeping)意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。磁盘休眠状态(disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

暂停状态(stopped)可以通过发送 SIGSTOP 信号给进程来停止进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

跟踪状态(tracing stop)当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。比如在gdb中对被跟踪的进程下一个断点,进程在断点处停下来的时候就处于 TASK_TRACED 状态。而在其他时候,被跟踪的进程还是处于前面提到的那些状态。

死亡状态(dead)是内核运行 kernel/exit.c 里的 do_exit() 函数返回的状态。这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

僵尸状态(zombie)是一个比较特殊的状态。有些人认为这个状态是在父进程死亡而子进程存活时产生的。实际上不是这样的。父进程可能已经死了但子进程依然存活着,那个子进程的父进程将会成为init进程。当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵尸进程。僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

各种状态之间的转换:

Sources: linusakesson.net, ufsc.br, macdesign.net.
僵尸进程
什么是僵尸进程?

我们知道退出一个进程用系统调用exit,但是这并不意味着该进程马上就消失了,事实上它还留下了一个被称为僵尸进程(Zombie)的数据结构。在Linux进程的5种状态中(R、S、D、T、Z),僵尸进程(Z)是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。从这点来看,僵尸进程虽然有一个很酷的名字,但它的影响力远远抵不上那些真正的僵尸兄弟,真正的僵尸总能令人感到恐怖,而僵尸进程却除了留下一些供人凭吊的信息,对系统毫无作用。

为什么会出现僵尸进程?
  • 僵尸进程就是子进程已经结束,但是父进程没有处理的进程!
  • 父进程可以使用 waitpid,wait4 等来处理僵尸进程!
  • 如果父进程不幸在子进程之前“死了”,那么子进程就交由init(pid == 1)进程去管理

即,父进程还没有来得及处理子进程的退出状态等信息,所以才会有僵尸进程的出现。

参考链接:

=END=

发表评论

电子邮件地址不会被公开。 必填项已用*标注