process management
进程是程序的执行实例,是操作系统资源分配的基本单位。
每个运行的程序在 Linux 中都是一个进程(具有独立的地址空间、代码段、堆、栈、数据段),包括 shell、nginx、mysqld、bash 等。
进程生命周期:
创建:通过 fork()、exec() 系列系统调用
就绪:等待内核调度
运行:CPU 调度运行中
阻塞:等待资源或事件(如 I/O)
终止:执行完毕或被杀死
僵尸:子进程结束但父进程未回收资源
进程状态
状态符 | 含义 | 说明 |
---|---|---|
R | Running | 正在运行或可运行状态 |
S | Sleeping | 可中断的休眠 |
D | Uninterruptible | 不可中断(一般是 I/O 阻塞) |
T | Stopped | 被暂停或调试 |
Z | Zombie | 僵尸状态,需父进程回收 |
X | Dead | 已终止(很少见) |
ps
ps
命令(process status 的缩写)用于报告当前系统中运行的进程快照。它提供了关于正在运行的进程的信息,包括它们的 PID(进程 ID)、TTY(终端)、运行时间、CPU 使用情况以及命令名称等。
ps
的语法非常灵活,因为它有多种风格的选项:
- UNIX 风格:以单破折号开头,如
ps -ef
。 - BSD 风格:不带破折号,如
ps aux
。 - GNU 风格:以双破折号开头,如
ps --forest
。
在实际使用中,通常会将不同风格的选项组合使用,这可能会导致一些混淆,但掌握一些常用的组合是关键。
核心功能与使用场景
ps
命令最常见的用途是查看进程列表。以下是一些核心的用法和它们的应用场景:
查看当前终端的进程:
Bash
1
ps
这是
ps
最简单的用法,它会显示当前与你的终端关联的进程。通常你会看到bash
(你的 shell)和ps
命令本身。查看所有进程(UNIX 风格):
Bash
1
ps -ef
- **
-e
**:选择所有进程。 - **
-f
**:以“完整”格式显示列表,包括 UID、PID、PPID(父进程 ID)、C(CPU 使用率)、STIME(启动时间)、TTY、TIME(CPU 时间)和 CMD(命令)。
这是在服务器运维中最常用的
ps
命令之一,因为它提供了详细且易读的进程信息。- **
查看所有进程(BSD 风格):
1
ps aux
- **
a
**:显示所有终端上的进程(包括其他用户的)。 - **
u
**:显示面向用户的格式(User-oriented format),包括 USER、PID、%CPU、%MEM、VSZ(虚拟内存大小)、RSS(常驻内存大小)、TTY、STAT(进程状态)、START(启动时间)、TIME 和 COMMAND。 - **
x
**:显示没有控制终端的进程。
ps aux
也是非常流行的一种用法,特别适合快速查看系统资源占用情况(%CPU, %MEM)。- **
选项解析与应用
ps
提供了大量的选项来定制输出。以下是一些在运维中非常有用的选项:
-o format 或 –format format: 自定义输出列。这是 ps 最强大的功能之一,允许你精确地选择想要的信息。
例如,只显示 PID、进程名称和 CPU 使用率:
1
ps -eo pid,comm,%cpu
常用的格式指定符包括:
pid
,ppid
,user
,group
,comm
(命令名),cmd
(完整命令行),%cpu
,%mem
,vsz
,rss
,stat
,tty
,time
,etime
(运行时间)。-p pid
: 仅显示指定 PID 的进程。1
ps -p 12345
当你需要追踪特定进程的状态时非常有用。
-u userlist
: 仅显示属于指定用户(或多个用户)的进程。1
ps -u nginx,apache
用于检查特定服务用户运行的进程,或排查某个用户引起的问题。
-C command
: 仅显示指定命令名的进程。Bash
1
ps -C nginx
用于查找所有
nginx
进程的实例,即使它们不是由同一个用户或在同一个 TTY 下运行。-l
: 显示长格式(long format)。提供了更多的技术细节,如进程优先级 (PRI
)、nice 值 (NI
) 等。Bash
1
ps -l
--forest
: 以 ASCII 艺术图形式显示进程树。这对于理解进程之间的父子关系非常有帮助。1
ps -ef --forest
或者结合
aux
风格:Bash
1
ps aux --forest
grep 组合使用: ps 的输出通常很大,结合 grep 进行过滤是常见操作。
例如,查找所有与 java 相关的进程:
1
ps -ef | grep java
注意: 使用
grep
时,grep
命令本身也会出现在输出中。为了避免这种情况,可以使用grep -v grep
或者更精确的正则表达式。1
ps -ef | grep '[j]ava' # 避免匹配 grep 进程本身
进程状态(STAT)字段解析
ps
输出中的 STAT
字段非常重要,它指示了进程的当前状态:
R
: Running 或 Runnable (正在运行或在运行队列中等待)。S
: Sleeping (可中断的睡眠状态,等待事件完成)。D
: Uninterruptible sleep (不可中断的睡眠状态,通常在等待 I/O 完成)。Z
: Zombie (僵尸进程,子进程已终止,但父进程尚未回收其资源)。T
: Stopped (被信号停止,如SIGSTOP
或SIGTSTP
)。<
: High-priority process (高优先级进程)。N
: Low-priority process (低优先级进程)。L
: Pages are locked into memory (内存页被锁定)。s
: Session leader (会话领导者)。+
: Foreground process group (前台进程组)。
实际应用场景
查找僵尸进程:
1
ps -ef | grep Z
僵尸进程可能表明父进程没有正确处理子进程的退出,长时间累积可能耗尽系统资源。
找出 CPU 或内存占用最高的进程:
1
2ps aux --sort=-%cpu | head -n 5 # 按 CPU 降序排序,显示前5个
ps aux --sort=-%mem | head -n 5 # 按内存降序排序,显示前5个这对于快速定位资源瓶颈非常有帮助。
检查特定服务的运行状态:
1
2ps -ef | grep nginx
ps -ef | grep mysql确认服务是否正在运行,以及运行了多少个工作进程。
根据端口查找进程:
这通常需要 lsof 或 netstat 的配合,但 ps 可以提供进程的详细信息:
1
lsof -i :80 | awk '{print $2}' | xargs ps -fp # 找出监听80端口的进程信息
查看守护进程(daemon):
守护进程通常没有控制终端。
1
ps axj # 显示所有进程,包括没有控制终端的,并以作业控制格式显示