`

Linux进程状态解析之T、Z、X

阅读更多
  • 摘要: Linux系统中进程有很多种状态,前面我们说了R、S、D三种状态,还有另外的三种状态,这里我们一并说一下,补全前面的文章。
  • 标签: Linux进程状态

上面一篇文章中我们介绍了Linux进程的R、S、D三种状态,这里接着上面的文章介绍另外三个状态。

Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。

向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态(除非该进程本身处于 TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL信号一样,是非常强制的。不允许用户进程通过 signal系列的系统调用重新设置对应的信号处理函数。)
向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。

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

对于进程本身来说,TASK_STOPPED和TASK_TRACED状态很类似,都是表示进程暂停下来。
而TASK_TRACED状态相 当于在TASK_STOPPED之上多了一层保护,处于TASK_TRACED状态的进程不能响应SIGCONT信号而被唤醒。只能等到调试进程通过 ptrace系统调用执行PTRACE_CONT、PTRACE_DETACH等操作(通过ptrace系统调用的参数指定操作),或调试进程退出,被调 试的进程才能恢复TASK_RUNNING状态。

Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。

进程在退出的过程中,处于TASK_DEAD状态。

在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。
之所以保留task_struct,是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。比如在shell中,$?变量就保存了最后一个退出的前台进程的退出码,而这个退出码往往被作为if语句的判断条件。
当 然,内核也可以将这些信息保存在别的地方,而将task_struct结构释放掉,以节省一些空间。但是使用task_struct结构更为方便,因为在 内核中已经建立了从pid到task_struct查找关系,还有进程间的父子关系。释放掉task_struct,则需要建立一些新的数据结构,以便让 父进程找到它的子进程的退出信息。

父进程可以通过wait系列的系统调用(如wait4、waitid)来等待某个或某些子进程的退出,并获取它的退出信息。然后wait系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉。
子进程在退出的过程中,内核会给其父进程发送一个信号,通知父进程来“收尸”。这个信号默认是SIGCHLD,但是在通过clone系统调用创建子进程时,可以设置这个信号。

通过下面的代码能够制造一个EXIT_ZOMBIE状态的进程:

#include   
void main() {  
    if (fork())  
    while(1) sleep(100);  
} 
 


编译运行,然后ps一下:

 kouu@kouu-one:~/test$ ps -ax | grep a\.out  
10410 pts/0    S+     0:00 ./a.out  
10411 pts/0    Z+     0:00 [a.out]   
10413 pts/1    S+     0:00 grep a.out 
 

 

只要父进程不退出,这个僵尸状态的子进程就一直存在。那么如果父进程退出了呢,谁又来给子进程“收尸”?
当进程退出的时候,会将它的所有子进程都托管给别的进程(使之成为别的进程的子进程)。托管给谁呢?可能是退出进程所在进程组的下一个进程(如果存在的话),或者是1号进程。所以每个进程、每时每刻都有父进程存在。除非它是1号进程。

1号进程,pid为1的进程,又称init进程。
linux系统启动后,第一个被创建的用户态进程就是init进程。它有两项使命:
1、执行系统初始化脚本,创建一系列的进程(它们都是init进程的子孙);
2、在一个死循环中等待其子进程的退出事件,并调用waitid系统调用来完成“收尸”工作;
init进程不会被暂停、也不会被杀死(这是由内核来保证的)。它在等待子进程退出的过程中处于TASK_INTERRUPTIBLE状态,“收尸”过程中则处于TASK_RUNNING状态。

Linux进程状态:X (TASK_DEAD - EXIT_DEAD),退出状态,进程即将被销毁。

而进程在退出过程中也可能不会保留它的task_struct。比如这个进程是多线程程序中被detach过的进程(进程?线程?参见《linux 线程浅析》)。或者父进程通过设置SIGCHLD信号的handler为SIG_IGN,显式的忽略了SIGCHLD信号。(这是posix的规定,尽管 子进程的退出信号可以被设置为SIGCHLD以外的其他信号。)
此时,进程将被置于EXIT_DEAD退出状态,这意味着接下来的代码立即就会将该进程彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。

进程的初始状态

进程是通过fork系列的系统调用(fork、clone、vfork)来创建的,内核(或内核模块)也可以通过kernel_thread函数创 建内核进程。这些创建子进程的函数本质上都完成了相同的功能——将调用进程复制一份,得到子进程。(可以通过选项参数来决定各种资源是共享、还是私有。)
那么既然调用进程处于TASK_RUNNING状态(否则,它若不是正在运行,又怎么进行调用?),则子进程默认也处于TASK_RUNNING状态。
另外,在系统调用调用clone和内核函数kernel_thread也接受CLONE_STOPPED选项,从而将子进程的初始状态置为 TASK_STOPPED。

进程状态变迁

进程自创建以后,状态可能发生一系列的变化,直到进程退出。而尽管进程状态有好几种,但是进程状态的变迁却只有两个方向——从TASK_RUNNING状态变为非TASK_RUNNING状态、或者从非TASK_RUNNING状态变为TASK_RUNNING状态。
也 就是说,如果给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNING状态), 然后再响应SIGKILL信号而退出(变为TASK_DEAD状态)。并不会从TASK_INTERRUPTIBLE状态直接退出。

进程从非TASK_RUNNING状态变为TASK_RUNNING状态,是由别的进程(也可能是中断处理程序)执行唤醒操作来实现的。执行唤醒的 进程设置被唤醒进程的状态为TASK_RUNNING,然后将其task_struct结构加入到某个CPU的可执行队列中。于是被唤醒的进程将有机会被 调度执行。

而进程从TASK_RUNNING状态变为非TASK_RUNNING状态,则有两种途径:
1、响应信号而进入TASK_STOPED状态、或TASK_DEAD状态;
2、 执行系统调用主动进入TASK_INTERRUPTIBLE状态(如nanosleep系统调用)、或TASK_DEAD状态(如exit系统调用);或 由于执行系统调用需要的资源得不到满足,而进入TASK_INTERRUPTIBLE状态或TASK_UNINTERRUPTIBLE状态(如 select系统调用)。
显然,这两种情况都只能发生在进程正在CPU上执行的情况下。

分享到:
评论

相关推荐

    linux进程管理

    下面将详细解析从给定文件中提取的关键知识点,包括Linux进程管理的常见概念、命令及其用途。 ### Linux进程管理 #### 基础概念 - **进程**:在Linux系统中,每一个运行的程序都是一个进程,它由一组相关的数据...

    Linux进程详解管理

    从给定的文件信息中,我们可以提取到关于Linux进程管理和监控的重要知识点,下面将详细解析这些内容。 ### Linux进程管理概述 在Linux系统中,进程是操作系统资源分配的基本单位,每个运行中的程序都是一个进程。...

    linux 性能优化.7z

    "Linux性能优化.7z"这个压缩包文件包含了多个PDF文档,旨在帮助用户理解和掌握如何提升Linux系统的运行效率。以下是对这些资源的主要知识点的详细阐述: 1. **《Linux性能优化大师》**:这本书可能是对Linux系统...

    Linux进程管理教程

    ### Linux进程管理教程知识点解析 #### 一、Linux系统特性 - **多用户特性**:Linux支持多个用户同时登录并使用系统,每个用户可以独立地运行自己的程序。 - **多工(多任务)特性**:Linux能够同时处理多个任务,...

    Linux操作系统PS命令详细解析.docx

    - `STAT`:进程状态,如D、R、S、T、W、X、Z等。 - `START`:进程启动时间。 - `TIME`:进程使用的CPU时间总和。 - `COMMAND`:进程执行的命令和参数。 **4. 应用举例** 例如,`ps -aux | more`命令将进程信息通过...

    ps命令输出进程状态S+的含义解析

    `ps`命令是Unix和Linux系统中用于报告当前系统中进程状态的实用程序。它能够显示各种关于进程的信息,如进程ID(PID)、用户、CPU使用率、内存使用情况以及进程的状态等。在讨论`ps`命令输出的进程状态时,我们需要...

    IBM 关于System Z 在Linux 系统相关技术资料的红皮书

    ### IBM System Z与Linux系统相关技术资料红皮书解析 #### 一、引言:IBM System Z 和 Linux 的结合 IBM System Z 是 IBM 公司的一款高性能大型机系统,其强大的计算能力、卓越的安全性和可靠性使其成为金融、政府...

    最新整理Linux操作系统的进程管理详解.doc

    - `STAT`:进程状态,如D(不可中断的睡眠)、R(可运行)、S(睡眠)、T(停止)、W(交换出)、X(死掉)、Z(僵尸)等。 - `START`:进程启动时间。 - `TIME`:进程消耗CPU的时间。 - `COMMAND`:命令名称和参数。 接下来,...

    Linux的top命令解析.docx

    - **S**:进程状态。D=不可中断的睡眠状态;R=运行;S=睡眠;T=跟踪/停止;Z=僵尸进程。 - **COMMAND**:命令名/命令行。 #### 五、交互式操作 `top`命令支持多种快捷键操作,用于更改显示内容或执行特定任务。 -...

    Linux的top命令解析_docx1

    11. **S** 进程状态(D-不可中断的睡眠,R-运行,S-睡眠,T-跟踪/停止,Z-僵尸进程) 12. **COMMAND** 进程名称或命令行 `top` 命令还支持一系列快捷键以方便操作,如: - **h 或 ?** 显示帮助信息 - **k** 终止...

    linux ps命令源码

    3. **进程状态解析**:源码会解释如何解析`/proc`文件中的数据,将它们转换为人类可读的格式。例如,解析`/proc/[pid]/stat`文件中的进程状态标志(如R表示运行,S表示睡眠,Z表示僵尸状态等)。 4. **选项处理**:...

    Linux shell命令初学解析

    ### Linux Shell命令初学解析 #### 目标 - 了解Shell的概念及其作用 - 掌握Shell的常用命令 - 学会使用vi编辑器 #### 一、了解Shell **Shell** 是用户与Linux操作系统之间的重要接口,它允许用户通过命令行的...

    Linux内核源代码情景(全册高清带书签).7z

    包括进程状态转换、上下文切换、进程间通信(IPC)等概念都是这部分的重点。 3. **内存管理** 内存管理涉及到虚拟地址空间、页表、物理内存分配与回收、内存分页和交换机制等内容。理解Linux如何有效地管理和优化...

    linux实验五_进程管理命令

    ### Linux实验五:进程管理命令 #### 一、实验目的 本实验旨在通过一系列实践操作,帮助学习者深入了解Linux系统中的进程管理。具体目标包括: 1. **了解如何监视系统运行状态**:通过使用`top`等命令,观察系统...

    操作系统linux版实验报告.doc

    1. **Linux进程状态**: - **R(Running or Runnable)状态**:进程正在执行或者在就绪队列等待CPU时间片。 - **S(Sleeping or Waiting)状态**:进程正在等待某个事件的发生,可以被中断。 - **D...

    Linux下如何查杀stopped进程详解

    总结起来,处理Linux系统中的"Stopped"进程,首先要理解各种进程状态,然后使用`ps`命令进行查询,最后通过`kill`命令发送适当的信号来终止进程。掌握这些技巧对于有效地管理Linux系统中的进程至关重要。希望本文...

    得到一个进程的状态,比如:进程是否没有响应

    在Linux环境下,我们通常使用`ps`命令行工具或`/proc`文件系统来获取进程状态。`/proc`目录下的每个子目录都代表一个进程ID,包含了一系列文件,如`status`文件提供了进程的基本信息,包括是否挂起(Z状态,即僵尸...

Global site tag (gtag.js) - Google Analytics