Linux 进程管理

1. 概念

进程(Process)是操作系统中的核心概念之一,指正在运行的程序实例。它是操作系统进行资源分配和调度的基本单位,为程序的执行提供了动态的上下文环境。

父子进程概念:父子进程是操作系统中进程管理的核心概念之一,描述了进程之间的创建关系。当一个进程(父进程)创建另一个新进程(子进程)时,二者形成父子关系。

父子进程的核心特性

  • 创建方式:父进程通过 fork()(Unix/Linux)或 CreateProcess()(Windows)创建子进程。
  • 资源继承:子进程继承父进程的代码段、数据段、文件描述符、环境变量等。
  • 独立性:子进程拥有独立的地址空间,修改数据不影响父进程。
  • 生命周期:父进程可以等待子进程结束(如 wait()),子进程也可能成为孤儿进程。

2. 进程的状态介绍

  • R:运行或就绪状态,进程正在CPU执行或在就绪队列等待。
  • S:可中断睡眠状态,等待I/O完成(如磁盘读写),可被信号唤醒。
  • D:不可中断睡眠状态,内核态阻塞(如硬件操作),即使信号也不能唤醒。常见于磁盘故障时。
  • T:暂停状态,进程被调试器暂停(如gdb)或收到SIGSTOP信号。
  • Z:僵尸状态,进程已终止但未被回收。
  • X:死亡状态,进程完全结束(极少见到,瞬间状态)。

3. 几种特殊进程介绍

  • 僵尸进程:指已经停止运行但未被其父进程回收状态信息的进程。
    • 影响:占用大量 pid,可能导致PID耗尽无法新建进程。
    • 解决方法:可以通过向其父进程发送信号回收僵尸进程,父进程不响应时只有通过杀掉父进程让 1 号进程接管回收僵尸进程。
  • 孤儿进程:父进程先于子进程运行结束时,子进程成为孤儿进程会被 1 号进程接管,通常无需干预。
  • 守护进程:一种在后台运行不需要与用户交互的特殊进程,在系统启动时启动,系统结束时结束。

4. 查看进程详细信息命令

ps 命令

1. 常用选项组合

查看当前终端关联的进程

ps -f  # 完整格式显示(UID, PID, PPID, CMD等)
ps -l  # 详细格式(包含优先级、内存占用等)
Bash

查看系统中所有进程

ps -e   # 显示所有进程(简略列表)
ps -ef  # 完整格式显示所有进程
ps -aux # BSD风格,显示所有进程及资源占用(常用)
Bash

按条件筛选进程

ps -u root          # 显示指定用户(如root)的进程
ps -p 1234,5678     # 显示指定PID的进程
ps -C nginx         # 显示指定命令名称(如nginx)的进程
Bash

显示进程树关系

ps -ejH   # 以树形结构显示进程层级
ps -e --forest  # 类似pstree的效果
Bash

查看线程信息

ps -T -p <PID>  # 显示指定进程的线程
ps -eLf         # 显示所有线程(LWP列)
Bash

2. 常见输出列含义

  • PID:进程ID。
  • PPID:父进程ID。
  • USER:进程所有者。
  • %CPU:CPU占用率。
  • %MEM:内存占用率。
  • VSZ:虚拟内存大小(KB)。
  • RSS:实际内存占用(KB)。
  • TTY:关联的终端。
  • STAT:进程状态(详细含义见下一小节)。
  • START:进程启动时间。
  • COMMAND/CMD:执行的命令。

3. 进程状态(STAT)

  • R:运行中(Running)。
  • S:可中断的睡眠(Sleeping)。
  • D:不可中断的睡眠(通常与I/O相关)。
  • T:停止(Stopped)。
  • Z:僵尸进程(Zombie,已终止但未回收)。
  • <:高优先级。
    • 进程的优先级(Priority)在 Linux/Unix 系统中决定了 CPU 资源分配的先后顺序,直接影响进程的响应速度和执行效率。
  • N:低优先级。
  • s:会话领导者(Session leader)。
  • L:多线程进程。
  • +:前台进程组。
  • I:内核空间的无任务空闲线程。
    • I 状态的进程是内核创建的 空闲线程,当 CPU 没有其他任务可执行时,会运行这些线程。它们不占用实际资源,仅用于填充 CPU 时间。

top 命令

1. 常用 top 启动参数

top -d 2              # 设置刷新间隔为 2 秒
top -p 1234,5678      # 仅监控指定 PID 的进程
top -u mysql          # 仅显示 mysql 用户的进程
top -b -n 3 > top.log # 以批处理模式运行 3 次并保存到日志
top -H -p 1234        # 查看某个进程的所有线程
Bash

2. top 交互命令

  • q:退出 top
  • h:显示帮助。
  • Space:立即刷新。
  • k:终止进程(输入 PID 后回车)。
  • r:调整进程优先级(renice)。
  • P:按 CPU 使用率排序。
  • M:按内存使用率排序。
  • T:按运行时间排序。
  • 1:显示所有 CPU 核心的详细使用率。
  • u:仅显示指定用户的进程。
  • Shift + > / Shift + <:切换排序方向。
  • z:切换颜色显示。
  • W:保存当前配置(下次启动 top 时生效)。

5. 管理进程相关命令

5.1. 进程优先级设置

关于进程的优先级,top 命令可以查看到两个相关的值 PR 与 NI。

  • PR:内核实际使用的动态优先级,值越小优先级越高(PR = 20 + NI,但实时进程例外)。
    • 在 Linux 系统中,实时进程(Real-Time Process) 是一类具有最高调度优先级的进程,能够立即抢占普通进程的 CPU 资源,通常用于对延迟极度敏感的任务(如音视频处理、工业控制等)。优先级范围 1–99(值越大优先级越高),此时 NI 值无效。
  • NI:用户可调整的静态优先级偏移量,范围为-20 到 +19,负值提高优先级(默认 0)。

调整进程优先级(修改 NI 值)

# 启动时设置 Nice 值
nice -n -5 /path/to/command   # 以高优先级(NI=-5)启动进程
nice -n 10 /path/to/command   # 以低优先级(NI=10)启动进程

# 调整运行中进程的 Nice 值
renice -n 5 -p 1234          # 将PID 1234的NI值改为5
renice -n -10 -u username    # 修改某用户所有进程的NI值

# 普通用户只能调低优先级(NI 值调高至 0–19)。
# 提高优先级(NI < 0)需 root 权限。
Bash

实时优先级(PR)调整(需 root)

# 实时进程优先级(1–99)通过 chrt 命令设置:
chrt -f -p 90 1234   # 将PID 1234设为SCHED_FIFO,优先级90
chrt -r -p 50 5678   # 将PID 5678设为SCHED_RR,优先级50

# -f:SCHED_FIFO(先进先出,独占CPU直到退出)。
# -r:SCHED_RR(时间片轮转)。
# -p:指定优先级(1–99,值越大优先级越高)。
Bash

5.2. 给进程发送信号命令

 发送信号的基本命令

# kill 命令
kill -<信号名或编号> <PID>
kill -9 1234       # 强制终止 PID 为 1234 的进程
kill -SIGTERM 5678 # 优雅终止 PID 为 5678 的进程

# pkill 命令(按进程名发送信号)
pkill -<信号名或编号> <进程名>
pkill -SIGHUP nginx   # 向所有 nginx 进程发送 SIGHUP(重新加载配置)
pkill -9 firefox      # 强制终止所有 firefox 进程

# killall 命令(按进程名批量发送信号)
killall -<信号名或编号> <进程名>
killall -SIGUSR1 python  # 向所有 python 进程发送 SIGUSR1
killall -9 chrome        # 强制终止所有 chrome 进程
Bash

常用信号列表

信号编号信号名默认行为用途
1SIGHUP终止挂起(常用于重新加载配置,如 nginx -s reload
2SIGINT终止键盘中断(Ctrl+C 触发)
3SIGQUIT终止 + 核心转储键盘退出(Ctrl+\ 触发)
9SIGKILL强制终止立即杀死进程(不可被捕获或忽略)
15SIGTERM终止默认终止信号(允许进程清理资源)
18SIGCONT继续运行恢复被 SIGSTOP 暂停的进程
19SIGSTOP强制暂停暂停进程(不可被捕获或忽略)
20SIGTSTP暂停终端暂停(Ctrl+Z 触发,可被捕获)
28SIGWINCH忽略窗口大小改变(如终端调整大小)
29SIGIO忽略异步 I/O 事件
30SIGUSR1终止用户自定义信号 1(由程序决定行为,如日志轮转)
31SIGUSR2终止用户自定义信号 2(由程序决定行为,如切换调试模式)

6. 进程间通信-管道的应用

在 Linux 系统中管道操作符号为 “|”,主要用来连接左右两个命令,将左侧的命令的标准输出传递到右侧命令的标准输入。
PS:无法传递标准错误输出

管道应用示例:

# 统计网站访问前十的 iP
## 打印所有访问的过来的ip | 排序 | 去重 | 倒序排序 | 取前10
awk '{print $1}' access.log |sort |uniq -c |sort -rn|head
Bash

tee 命令的应用

示例:

# 提取当前系统的 IPv4 地址并保存到文件 ip.txt,同时输出到屏幕。
ip address |grep 'inet ' |awk -F"/" '{print $1}' |awk '{print $2}' |tee ip.txt

tee -a ip.txt # 参数 -a 表示追加
Bash

xargs 命令的应用

基本功能

  • 作用:将输入数据(如文件列表、文本行)作为参数传递给其他命令(如 rmcpgrep 等)。
  • 典型场景:当命令不支持管道输入(如 rm 不能直接 cat files.txt | rm),但需要批量操作时。

基础语法

command1 | xargs [options] command2

# command1 生成输入数据(如 ls、find)。
# xargs 将数据分割成参数传递给 command2。
Bash

常用选项

  • -n NUM:每次调用命令时传递的最大参数个数(分批处理)。
  • -I {}:定义替换字符串(常用 {} 或 %),参数可插入到命令指定位置。
  • -p:交互式模式,执行前确认。
  • -t:打印要执行的命令(调试用)。
  • -d :指定输入分隔符(默认是空格和换行)。
  • -0:以 \0 作为分隔符(通常与 find -print0 配合处理含空格的文件名)。

用法示例

# 批量删除文件
find . -name "*.log" | xargs rm -f
## 等效于:rm -f $(find . -name "*.log")
## 如果文件名含空格会出错,可使用如下命令:
find . -name "*.log" -print0 | xargs -0 rm -f

# 分批处理参数
echo {1..100} | xargs -n 10 echo
## 每行输出10个数字:
## 1 2 3 4 5 6 7 8 9 10
## 11 12 13 ... 20

# 替换参数位置
find . -name "*.txt" | xargs -I {} cp {} /backup/
## 将找到的每个文件复制到 /backup/ 目录

# 并行执行(结合 -P)
cat urls.txt | xargs -n 1 -P 3 curl -O
## 每次下载1个URL,同时最多3个并行下载
Bash


上一篇
下一篇