Linux下的进程状态
一般来说, Linux中的进程状态主要有如下几种:
1. R (TASK_RUNNING),可执行状态。
2. S (TASK_INTERRUPTIBLE),可中断的睡眠状态。
3. D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。
4. T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
5. Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。
6. X (TASK_DEAD - EXIT_DEAD),退出状态,进程即将被销毁。
R(TASK_RUNNING),可执行状态
只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构被放入对应CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。调度器负责从可执行队列中选择一个进程在CPU上运行.
S(TASK_INTERRUPTIBLE),可中断的睡眠状态。
将进程调用了会引起阻塞的api(如sem_wait,read, recv, recvfrom, sleep)后, 可能被设置为这种状态, 处于这种状态的进程暂时不会被调度. 注意这里可中断的含义是可以被信号中断,意味着进程此时是可以处理信号的.
通过ps -x命令我们会看到,大多数进程都处于TASK_INTERRUPTIBLE状态。如果不是, 那么此时的进程数量和CPU负载应该是非常高的.
这里有一个例子可以深入理解可中断的含义.
<pre name="code" class="cpp">#include <signal.h>
#include <stdio.h>
void int_handler(int signum)
{
printf("\nSIGINT signal handler.\n");
}
int main()
{
signal(SIGINT, int_handler);
printf("int_handler set for SIGINT\n");
while(1)
{
printf("go tosleep.\n");
sleep(60);
}
return 0;
}
执行之后, 输入ctrl+c的打印如下
可以看出, sleep被信号给中断了.
D(TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。
与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的。不可中断指的是进程不响应异步信号(这意味着我们使用kill -9无法杀死进程)。
我们通过vfork系统调用可以比较容易重现TASK_UNINTERRUPTIBLE状态。当执行vfork系统调用后,父进程将进入TASK_UNINTERRUPTIBLE状态,直到子进程调用exit或exec.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void main()
{
if (!vfork())
sleep(100);
}
编译完成后, 执行./a.out, 然后执行 ps –x | grep a.out
这时候我们发现kill -9无法杀死处理D状态的父进程.
T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
当进程运行于前台的时候, 输入ctrl+z或者向进程kill –SIGTSTP 消息, 可以让进程变为停止状态. 处于停止状态的进程不再执行, 可以用fg命令将它重新切换到前台执行.
Z (TASK_DEAD - EXIT_ZOMBIE),僵尸进程
当一个进程退出时,它并不是完全消失,而是等到它的父进程发出wait系统调用才会完全消失,除非父进程发出wait系统调用终止进程,否则该进程将一直处于所谓的僵死状态,等待它的父进程终止它.如果父进程终止了运行而没有撤销子进程,那么这些进程将被进程init收养.init进程定期调用wait来完成僵尸进程的清理.
以下代码可以制造出僵尸进程:
<pre name="code" class="cpp">#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main ()
{
if(!fork()){
printf("childpid=%d\n", getpid());
exit(5);
}
sleep(20);
printf("parent pid=%d\n",getpid());
exit(EXIT_SUCCESS);
}
最后PS -x命令还有四种附加状态:
W状态:不驻留内存
<状态:nice小于0
N状态:nice大于0
L状态:有锁住的页面