Linux中进程的状态

Linux中进程的状态
Photo by Luis Lopes / Unsplash

6/100

在Linux源码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[] = {

	/* states in TASK_REPORT: */
	"R (running)",		/* 0x00 */
	"S (sleeping)",		/* 0x01 */
	"D (disk sleep)",	/* 0x02 */
	"T (stopped)",		/* 0x04 */
	"t (tracing stop)",	/* 0x08 */
	"X (dead)",		/* 0x10 */
	"Z (zombie)",		/* 0x20 */
	"P (parked)",		/* 0x40 */

	/* states beyond TASK_REPORT: */
	"I (idle)",		/* 0x80 */
};

随着内核版本的更新,进程的被定义的状态也会有所不同。在14年的版本的array.c中就没有定义Parked和Idle状态。

我们先来关注这几种状态:

  • Running or Runnable (R)
  • Uninterruptible Sleep (D)
  • Interruptable Sleep (S)
  • Stopped (T)
  • Zombie (Z)

通过top命令可以看到进程的状态:

Running or Runnable(R)

启动一个新的进程便会进入Running的状态,运行一段时间后CPU会让该进程让出CPU的占用权,以便让其他进程使用CPU.与之前进程有关的信息会保留在内存中,进程则会被移到一个Queue中等待CPU的下一次调度.

在Queue中等待执行的进程就属于Runnable状态.虽然Runnable与Running是两种不同的进程状态.但均使用R来标记.

Interruptable Sleeping(S) and Uninterruptable Sleeping(D)

可中断的睡眠状态(S)与不可中断的睡眠状态(D)均代表进程处于等待其他资源的状态.当进程在执行的过程中有可能需要对IO资源(文件,网络等)进行操作,当这些外部资源未准备好的时候进程可能无法继续.

因此,为了不浪费CPU的计算能力,处于上述情况的进程应当让出CPU然后等待(Sleep)其他资源准备就绪.

D状态的进程意味着它正处于内核空间中(执行了某个系统调用).在其他资源没有就绪的时候,不会相应任何中断信号.只有当资源就绪才会变成Running状态.而S状态的进程除了在等待其他资源准备就绪也会响应外部的中断信号.

怎么处理D状态的进程

根据网络上的资料显示,D状态的进程正如它所代表的含义一样"不可中断",所以不会响应像kill -9这样的SIGKILL信号.只能通过重启机器或者让进程所需要的资源准备就绪.

系统出现大量的D状态的进程会有什么表现?

这其实是一道面试题,当时没有答上来,自己也没遇到过类似的情况.如果你知道欢迎发邮件告诉我~

Stopped(T)

R状态的进程可以通过接受SIGSTOP和SIGSTP信号来进入T状态.

SIGSTOP通过kill -SIGSTOP命令来发送,进程必须接受(处于R状态的进程)并作出响应动作然后进入T状态.

SIGSTP通过Ctrl-Z组合键发送,与SIGSTOP不同的是进程可以忽略这个信号(接受信号后继续执行程序)

处于T状态的进程可以通过接受SIGCONT信号重新进入R状态.

Zombie(Z)

进程执行完毕或者收到了终止的信号(SIGTERM),会向父进程发送SIGCHLD信号然后进入Z状态,直到父进程通过系统调用wait() 或者 waitpid() 接受子进程的退出码(exit code) 才能从进程表中清除,否则将一直保持Z状态.(也就是说只有父进程可以处理Z进程)

使用PS命令查看进程状态

除了使用top命令,ps命令也可以查看进程状态.ps展示的进程状态会稍稍有些不同.

在STAT列除了有I/S还会有Ss/I<这样的状态.通常情况下我们只需要关注第一个字母,它代表了进程所处的状态.后面跟随的其他字母或者符号可以通过man page查询到:

       Here are the different values that the s, stat and state output
       specifiers (header "STAT" or "S") will display to describe the
       state of a process:

               D    uninterruptible sleep (usually IO)
               I    Idle kernel thread
               R    running or runnable (on run queue)
               S    interruptible sleep (waiting for an event to
                    complete)
               T    stopped by job control signal
               t    stopped by debugger during the tracing
               W    paging (not valid since the 2.6.xx kernel)
               X    dead (should never be seen)
               Z    defunct ("zombie") process, terminated but not
                    reaped by its parent

       For BSD formats and when the stat keyword is used, additional
       characters may be displayed:

               <    high-priority (not nice to other users)
               N    low-priority (nice to other users)
               L    has pages locked into memory (for real-time and
                    custom IO)
               s    is a session leader
               l    is multi-threaded (using CLONE_THREAD, like NPTL
                    pthreads do)
               +    is in the foreground process group

Summary

以上这些内容是在面试时遇到的一些没能回答的问题,如果你发现上面的内容有误欢迎通过邮件的方式告诉我.

Ref:

https://www.baeldung.com/linux/process-states