Linux进程相关
Linux/Unix 进程状态码总结
下面是 ps
命令输出中 STAT
(或 S
) 列可能出现的状态码及其含义。状态码通常由一个主状态字符和可能的附加字符组成。
主要状态码 (Main States)
状态码 | 名称 (英文) | 名称 (中文) | 详细解释 |
---|---|---|---|
R |
Running or Runnable | 运行或可运行 | 进程正在 CPU 上执行,或者在运行队列中等待被 CPU 调度。这是进程唯一真正在“工作”的状态。 |
S |
Interruptible Sleep | 可中断睡眠 | 最常见的状态。进程正在等待某个事件(如 I/O、网络数据、用户输入),可以被信号唤醒。不消耗 CPU。 |
D |
Uninterruptible Sleep | 不可中断睡眠 | 进程正在等待 I/O 操作(通常是磁盘 I/O),无法被任何信号(包括 kill -9 )中断。只能等待 I/O 完成或重启系统。 |
Z |
Zombie (Defunct) | 僵尸进程 | 进程已经终止,但其父进程尚未读取其退出状态(未“收尸”)。不占用内存或 CPU,只在进程表中保留一个条目。 |
T |
Stopped or Traced | 停止或被跟踪 | 进程被信号暂停。通常是用户按 Ctrl+Z (SIGTSTP) 或由调试器 (gdb) 控制 (SIGTRAP) 导致。 |
X |
Dead | 死亡进程 | 一个不应被看到的状态,非常罕见。表示进程已经被彻底清理。 |
附加状态码 (Additional Modifiers)
这些字符可以附加在主要状态码之后,提供更多上下文信息。
附加码 | 名称 (英文) | 名称 (中文) | 详细解释 |
---|---|---|---|
< |
High-priority (niced to -) | 高优先级 | 进程的 nice 值小于 0,拥有比普通进程更高的调度优先级。 |
N |
Low-priority (niced to +) | 低优先级 | 进程的 nice 值大于 0,拥有比普通进程更低的调度优先级。会“友好地”让出 CPU 资源。 |
L |
Pages locked into memory (for I/O) | 内存页面锁定 | 进程有某些内存页面被锁定在物理内存中,通常是为了实时操作或直接 I/O。 |
s |
Session Leader | 会话领导者 | 该进程是一个会话组的领导者。通常是 shell 或启动一组相关进程的父进程。 |
l |
Multi-threaded (using CLONE_THREAD) | 多线程进程 | 进程是多线程的。在 ps 的 -L 选项下,你会看到每个线程(LWP)的状态,但只有主线程会显示 l 。 |
+ |
In the foreground process group | 前台进程组 | 进程属于当前终端的前台进程组,可以直接与用户交互并接收键盘输入。 |
t |
Traced by debugger | 被调试器跟踪 | 这是 T 状态的一个特例,明确表示进程是被一个调试器(如 gdb)暂停的。在现代系统中不常用,通常直接显示为 T 。 |
示例解读
R+
: 一个正在前台运行或等待运行的进程。Ss
: 一个作为会话领导者,并且正在可中断睡眠的进程。Sl+
: 一个多线程的、正在前台运行,并且当前处于睡眠状态的进程。Z
或Zs
: 一个僵尸进程(可能曾经是会话领导者)。T
: 一个被暂停的后台进程。D
: 一个正在等待磁盘读写,无法杀死的进程。SN
: 一个低优先级的睡眠进程。
查找进程
ps aux | grep [进程名或关键词]
除去僵尸进程(z状态)
ps -o ppid,stat,command -p 5812
找到僵尸进程的父进程,5812是僵尸进程的id
- 温和杀死
kill id
- 强制杀死
kill -9 id
子进程相关
python3 os.waitpid(pid, options)
参数一:pid
(要等待的进程ID)
这个参数决定了你要等待哪个或哪些子进程。
-
pid > 0
:- 含义: 只等待进程ID 等于
pid
的那一个特定的子进程。 - 示例:
os.waitpid(child_pid, 0)
只会等待child_pid
这个进程结束。
- 含义: 只等待进程ID 等于
-
pid == 0
:- 含义: 等待任何一个与当前进程在同一个进程组 (Process Group) 的子进程。
- 用途: 这在需要管理一组协同工作的子进程时很有用,但日常使用中不如
pid > 0
或pid == -1
常见。
-
pid == -1
:- 含义: 等待任何一个子进程。只要当前进程有任何一个子进程结束了,
waitpid
就会返回。这是最常用的“等待任意子进程”的方式。 - 与
os.wait()
的关系:os.wait()
实际上就等价于os.waitpid(-1, 0)
。
- 含义: 等待任何一个子进程。只要当前进程有任何一个子进程结束了,
-
pid < -1
:- 含义: 等待任何一个其进程组ID等于
pid
的绝对值的子进程。 - 用途: 这是一种更高级的用法,用于管理特定的进程组,不常用。
- 含义: 等待任何一个其进程组ID等于
参数二:options
(选项标志位)
这个参数是一个整数,通过位运算的“或” (|
) 来组合不同的标志,从而改变 waitpid()
的行为。
-
options = 0
(默认值):- 含义: 阻塞式等待 (Blocking Wait)。
- 行为: 如果没有符合
pid
条件的子进程已经终止,那么os.waitpid()
会暂停当前父进程的执行,一直“卡”在那里,直到有一个子进程结束,它才会返回。
-
options = os.WNOHANG
:- 含义: 非阻塞式轮询 (Non-blocking Poll)。
NOHANG
的意思就是“不要挂起”。 - 行为:
os.waitpid()
会立即返回,绝不等待。- 如果恰好有一个符合条件的子进程已经结束了,它会像正常情况一样返回
(pid, status)
,并清理那个僵尸子进程。 - 如果没有符合条件的子进程结束,它不会等待,而是会立即返回一个特殊的元组
(0, 0)
。
- 如果恰好有一个符合条件的子进程已经结束了,它会像正常情况一样返回
- 用途: 这非常有用!你可以把它放在一个循环里,一边做其他工作(比如读取子进程的输出),一边“轮询”子进程是否结束,而不会让主程序卡死。
- 含义: 非阻塞式轮询 (Non-blocking Poll)。
-
options = os.WUNTRACED
:- 含义: 除了关心子进程的终止,也关心它被暂停 (Stopped) 的情况。
- 行为: 如果一个子进程被信号(如
SIGSTOP
或SIGTSTP
,通常由Ctrl+Z
产生)暂停了,waitpid
也会返回。返回的status
需要用os.WIFSTOPPED(status)
来检查。 - 用途: 主要用于编写 shell 或调试器,需要对进程的各种状态变化做出反应。
-
options = os.WCONTINUED
:- 含义: 除了关心终止和暂停,也关心一个被暂停的子进程被恢复继续运行 (Continued) 的情况。
- 行为: 如果一个被暂停的子进程收到了
SIGCONT
信号并恢复运行,waitpid
也会返回。返回的status
需要用os.WIFCONTINUED(status)
来检查。 - 用途: 同样主要用于 shell 或调试器。