在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 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
R Running or runnable (on run queue)——“等待运行”
在该状态下进程可在CPU上运行,由于同一时间可以有多个进程同时为R状态,这些进程的task_struct(PCB)会被放入可执行队列里(我们只能确定的是这个进程会运行,但并不能确定该进程此时就在运行,它只是处于该状态而已)。
在CPU上运行的进程的状态是 RUNNING状态,在队列里等待运行的进程出于READDY状态。这两种状态在linux下统一为 TASK_RUNNING状态。
S Interruptible sleep (waiting for an event to complete)——休眠状态
S被称为“浅度睡眠”(可中断睡眠)。当进程因等待某事件的发生而被挂起,进程的task_struct被放入等待队列里。
在此状态下,进程虽然不运行,但却仍然在执行sleep部分的代码,可以响应所有的控制信息。
D Uninterruptible sleep (usually IO)
D一般被称为“深度睡眠”(不可中断睡眠)。
该状态不可被唤醒,只有自己才能唤醒自己。所以就无法使用kill命令杀死该进程,只有重启虚拟机。
不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。
一般是在等待I/O时,进程处于该状态。该状态之所以设置为不可中断,这里可以这样理解:假设操作系统需要从硬盘中读1G的数据,这时的进程应处于D状态,否则当硬盘将数据取好后,进程已经被杀死,那硬盘取好的数据无法安放,这是就有可能造成读取错误。
T (task_stopped) Stopped, either by a job control signal or because it is being traced.
该状态不处理任何代码
t task_traced追踪状态
“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。
X dead (should never be seen)
死亡状态,进程处于死亡状态才能被回收。
Z Defunct (“zombie”) process, terminated but not reaped by its parent.
僵尸状态。在进程退出后到进程回收前,进程为Z状态。
这种状态比较特别,它已经退出/结束了进程,却会以终⽌止状态保持在进程表中,并且会⼀一直在等待⽗父进程读取退出状态代码。
僵尸进程基本归还了所有的内存空间,除了存储着进程退出时的信息以供父进程读取。
僵尸进程一般是在被读取完信息后被其父进程回收,孤儿进程例外,它是被init进程回收。
孤儿进程:一个父进程退出 ,而他的一个或多个子进程还在运行,那么这些进程被称为孤儿进程。
孤⼉儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。