Linux下的进程状态

来源:互联网 发布:手机淘宝充值中心在哪 编辑:程序博客网 时间:2024/06/03 04:11

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状态,直到子进程调用exitexec.

#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状态:有锁住的页面

 

0 0