系统管理 - Linux系统进程管理

1. 什么是进程

进程是已启动的可执行程序的运行实例,进程有以下组成部分:

  • 分配内存: 已分配内存的地址空间
  • 安全属性: 进程的运行身份和权限
  • 进程代码: 运行一个或多个的线程
  • 进程状态: 进程运行后的多种状态

1.1 静态程序与动态进程

类型 说明 示例
静态程序 二进制文件 /bin/ls, /usr/sbin/sshd
动态进程 程序运行的过程, 有生命周期及运行状态 正在运行的进程

1.2 进程的运行环境

进程的运行环境,包括以下几个部分:

  • 局部和全局变量
  • 当前的调度上下文
  • 分配给进程使用的系统资源,例如文件描述符、网络端口等
  • 给进程分配对应的pid, ppid

2. 进程生命周期

程序运行时进程的状态关系:

  1. 父进程复制自己的地址空间创建新的子进程,子进程可以继承父进程(ppid)的环境变量

  2. 每个进程都有自己的唯一ID(PID)

  3. 进程是由systemd这个父进程派生出来的子进程

  4. 子进程在运行自己的程序代码的时候, 父进程往往会进入到睡眠状态

  5. 子进程完成程序代码发出退出信号请求

  6. 子进程已经关闭或丢弃了其资源环境, 剩余的部分称之为僵停(僵尸Zombie)

  7. 父进程在子进程退出时收到信号会被唤醒, 清理剩余的结构,然后继续执行其自己的程序代码

2.1 进程生命周期图

1
2
3
4
5
6
7
8
9
父进程 (systemd)
↓ (fork)
子进程创建
↓ (exec)
子进程运行
↓ (exit)
子进程退出
↓ (wait)
父进程清理

3. 监控和管理进程

在多任务处理操作系统中,每个CPU(或核心)在一个时间点上只能处理一个进程。

在进程运行时,它对 CPU 时间和资源分配的要求会不断变化,从而为进程分配一个状态,它随着环境要求而改变。

3.1 静态监控进程

静态查看进程通常使用ps命令

了解进程如下选项:

  • PID, PPID: 进程ID和父进程ID
  • 当前的进程状态: 进程运行状态
  • 内存的分配情况: 内存使用情况
  • CPU 和已花费的时间: CPU使用情况
  • 用户UID决定进程的特权: 进程运行用户

ps命令基本使用

1
2
3
[root@liyanzhao ~]# ps aux|less
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 46276 5836 ? Ss Feb27 0:46 /usr/lib/systemd/systemd --system --deserialize 21

ps命令字段说明

字段 说明
USER 运行进程的用户
PID 进程 ID
%CPU CPU 占用率
%MEM 内存占用率
VSZ 占用虚拟内存
RSS 占用实际内存 驻留内存
TTY 进程运行的终端
STAT 进程状态
START 进程的启动时间
TIME 进程占用 CPU 的总时间
COMMAND 进程文件,进程名

STAT进程状态详解

状态 说明
R 进程运行
S 可中断睡眠
D 不可中断睡眠
Z 僵尸进程
X 进程已经退出
T 进程被暂停
Ss/s 进程的领导者,父进程
S<</< 优先级较高的进程
SN/N 优先级较低的进程
R+ 表示是前台的进程组
Sl 以线程的方式运行

查看详细状态说明: man ps (搜索 /STATE)

ps命令使用方法

对进程的CPU进行排序展示:

1
2
3
4
5
# 按CPU使用率升序排序
[root@liyanzhao ~]# ps aux --sort %cpu |less

# 按CPU使用率降序排序
[root@liyanzhao ~]# ps aux --sort -%cpu |less

自定义显示字段:

1
2
3
[root@liyanzhao ~]# ps axo user,pid,ppid,%mem,command |grep nginx
root 122914 1 0.0 nginx: master process nginx
nginx 122915 122914 0.1 nginx: worker process

显示进程的子进程:

1
2
3
4
5
[root@liyanzhao ~]# yum install nginx -y
[root@liyanzhao ~]# systemctl start nginx
[root@liyanzhao ~]# ps auxf |grep nginx
root 122914 0.0 0.0 46308 956 ? Ss 17:32 0:00 nginx: master process nginx
nginx 122915 0.0 0.1 48780 1976 ? S 17:32 0:00 \_ nginx: worker process

查看指定进程PID:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 使用ps和grep
[root@liyanzhao ~]# ps aux|grep sshd
root 1157 0.0 0.1 105996 3604 ? Ss Feb27 0:00 /usr/sbin/sshd -D

# 查看PID文件
[root@liyanzhao ~]# cat /run/sshd.pid
1157

# 使用pgrep命令
[root@liyanzhao ~]# pgrep sshd
1157
118579

# 使用pidof命令
[root@liyanzhao ~]# pidof sshd
118579 1157

pgrep常用参数:

1
2
3
4
5
6
7
8
9
# -l 显示进程名
[root@liyanzhao ~]# pgrep -l sshd
1157 sshd
118579 sshd

# -a 显示完整命令行
[root@liyanzhao ~]# pgrep -a sshd
1157 /usr/sbin/sshd -D
118579 sshd: liyanzhao [priv]

查看进程树:

1
2
3
4
5
[root@liyanzhao ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─sshd───sshd───bash
├─nginx───nginx
└─...

3.2 动态监控进程

top命令基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 启动top命令
[root@liyanzhao ~]# top

# 设置刷新间隔为1秒
[root@liyanzhao ~]# top -d 1

# 查看指定进程的动态信息
[root@liyanzhao ~]# top -d 1 -p 10126

# 查看多个指定进程
[root@liyanzhao ~]# top -d 1 -p 10126,1

# 查看指定用户的进程
[root@liyanzhao ~]# top -d 1 -u apache

# 将2次top信息写入到文件
[root@liyanzhao ~]# top -d 1 -b -n 2 > top.txt

top常见指令

指令 功能
h 查看帮助
z 以彩色信息展示
1 显示所有CPU的负载
s 设置刷新时间
b 高亮显示处于R状态的进程
M 按内存使用百分比排序输出
P 按CPU使用百分比排序输出
R 对排序进行反转
f 自定义显示字段
k kill掉指定PID进程
W 保存top环境设置 ~/.toprc
q 退出

系统负载的计算和意义

进程以及子进程和线程产生的计算指令都会让cpu执行,产生请求的这些进程组成”运行队列”,等待cpu执行,这个队列就是系统负载, 系统负载是所有cpu的运行队列的总和.

1
2
[root@liyanzhao ~]# w
20:25:48 up 95 days, 9:06, 1 user, load average: 2.92, 0.00, 0.00

负载计算示例:

1
2
3
4
5
6
# 假设当前计算机有4个核心的cpu,当前的负载是2.92
cpu1 cpu2 cpu3 cpu4
2.94/4(个cpu核心) = 73%的cpu资源被使用,剩下27%的cpu计算资源是空闲的

# 假设当前的计算有2个核心的cpu,当前的负载是2.92
2.92/2 = 146% 已经验证超过了cpu的处理能力

负载平均值说明:

  • load average: 2.92, 0.00, 0.00
    • 第一个值(2.92): 1分钟平均负载
    • 第二个值(0.00): 5分钟平均负载
    • 第三个值(0.00): 15分钟平均负载

负载判断标准:

  • 负载 < CPU核心数: 系统正常
  • 负载 = CPU核心数: 系统满载
  • 负载 > CPU核心数: 系统过载,需要优化

4. 信号管理进程

使用kill命令发送信号与进程通信

用途:

  • 定义守护进程的角色
  • 结束用户会话和进程

相关命令: kill, killall, pgrep, pkill

4.1 常见信号列表

1
[root@liyanzhao ~]# kill -l  # 列出所有支持的信号
数字信号 信号别名 作用
1 HUP 挂起信号,往往可以让进程重新配置
2 INT 中断信号,起到结束进程的作用,和ctrl + c 的作用一样
3 QUIT 让进程退出,结果是进程退出
9 KILL 直接结束进程,不能被进程捕获
15 TERM 进程终止,这是默认信号
18 CONT 被暂停的进程将继续恢复运行
19 STOP 暂停进程
20 TSTP 用户停止请求,作用类似于ctrl + z 把进程放到后台并暂停

4.2 kill命令发送信号

给vsftpd进程发送信号

1
2
3
4
5
6
7
8
9
10
11
# 安装vsftpd
[root@liyanzhao ~]# yum -y install vsftpd
[root@liyanzhao ~]# systemctl start vsftpd

# 发送重启信号,例如 vsftpd 的配置文件发生改变,希望重新加载
[root@liyanzhao ~]# kill -1 9160

# 发送停止信号,vsftpd 服务有停止的脚本 systemctl stop vsftpd
[root@liyanzhao ~]# kill 9160
# 或
[root@liyanzhao ~]# kill -15 9160

给vim进程发送信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建测试文件
[root@liyanzhao ~]# touch file1 file2

# 使用远程终端1打开file1
[root@liyanzhao ~]# tty
/dev/pts/1
[root@liyanzhao ~]# vim file1

# 使用远程终端2打开file2
[root@liyanzhao ~]# tty
/dev/pts/2
[root@liyanzhao ~]# vim file2

# 查看当前进程pid
[root@liyanzhao ~]# ps aux |grep vim
root 4362 0.0 0.2 11104 2888 pts/1 S+ 23:02 0:00 vim file1
root 4363 0.1 0.2 11068 2948 pts/2 S+ 23:02 0:00 vim file2

# 发送15信号(优雅终止)
[root@liyanzhao ~]# kill 4362

# 发送9信号(强制终止)
[root@liyanzhao ~]# kill -9 4363

批量发送信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 还可以同时给所有vim进程发送信号, 模糊匹配,同时给多个进程发送信号
[root@liyanzhao ~]# killall vim

# 使用pkill踢出从远程登录到本机的用户, pkill 类似killall
[root@liyanzhao ~]# w
20:50:17 up 95 days, 9:30, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
xuliangw pts/0 115.175.115.39 20:22 0.00s 0.01s 0.00s sshd: liyanzhao [priv]

# 终止 pts/0上所有进程, 除了bash本身
[root@liyanzhao ~]# pkill -t pts/0

# 终止pts/0上所有进程, 并且bash也结束(用户被强制退出)
[root@liyanzhao ~]# pkill -9 -t pts/0

# 列出liyanzhao用户的所有进程,-l输出pid
[root@linux-liyanzhao ~]# pgrep -l -u liyanzhao
32206 sshd
32207 bash

4.3 信号使用建议

信号 使用场景 说明
TERM (15) 正常终止进程 默认信号,进程可以捕获并清理资源
KILL (9) 强制终止进程 无法捕获,立即终止,可能导致数据丢失
HUP (1) 重新加载配置 常用于服务进程重新读取配置文件
STOP (19) 暂停进程 进程暂停,不释放资源
CONT (18) 恢复进程 恢复被暂停的进程

5. 后台进程管理

作业控制是一个命令行功能,允许一个 shell 实例来运行和管理多个命令。

如果没有作业控制,父进程 fork()一个子进程后,将 sleeping,直到子进程退出。

使用作业控制,可以选择性暂停,恢复,以及异步运行命令,让 shell 可以在子进程运行期间返回接受其他命令。

5.1 前台进程与后台进程

类型 说明 特点
前台进程 在当前终端运行的进程 占用终端,可以交互
后台进程 在后台运行的进程 不占用终端,可以继续输入命令

5.2 后台进程管理命令

命令 功能
command & 在后台运行命令
jobs 查看后台作业
bg %n 让作业n在后台运行
fg %n 将作业n调回到前台
kill %n 终止作业n
Ctrl+Z 将前台进程挂起到后台
Ctrl+C 终止前台进程
Ctrl+B 后台运行(某些shell)

5.3 后台进程管理示例

示例1: 后台运行进程

1
2
3
4
5
6
7
8
9
10
# 运行程序(时),让其在后台执行
[root@liyanzhao ~]# sleep 3000 &

# 将前台的程序挂起(暂停)到后台
[root@liyanzhao ~]# sleep 4000
# 按 Ctrl+Z
[2]+ Stopped sleep 4000

# 查看进程
[root@liyanzhao ~]# ps aux |grep sleep

示例2: 查看后台作业

1
2
3
4
# 查看后台作业
[root@liyanzhao ~]# jobs
[1]- Running sleep 3000 &
[2]+ Stopped sleep 4000

作业状态说明:

  • Running: 正在运行
  • Stopped: 已停止
  • Done: 已完成
  • +: 最近一个作业
  • -: 倒数第二个作业

示例3: 控制后台作业

1
2
3
4
5
6
7
8
# 让作业2在后台运行
[root@liyanzhao ~]# bg %2

# 将作业1调回到前台
[root@liyanzhao ~]# fg %1

# kill作业1,终止PID为1的进程
[root@liyanzhao ~]# kill %1

示例4: 后台运行并重定向输出

1
2
3
4
5
# 进程在后台运行,但输出依然在当前终端
[root@liyanzhao ~]# (while :; do date; sleep 2; done) &

# 进程在后台运行,输出重定向到/dev/null
[root@liyanzhao ~]# (while :; do date; sleep 2; done) &>/dev/null &

5.4 nohup命令

nohup命令可以让进程在后台运行,即使终端关闭也不会终止。

1
2
3
4
5
# 使用nohup运行后台进程
[root@liyanzhao ~]# nohup command &

# 输出重定向
[root@liyanzhao ~]# nohup command > output.log 2>&1 &

5.5 screen和tmux

对于长时间运行的任务,建议使用screentmux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装screen
yum install -y screen

# 启动screen会话
screen -S session_name

# 在screen中运行命令
command

# 分离screen会话(按Ctrl+A,然后按D)
# 重新连接screen会话
screen -r session_name

# 列出所有screen会话
screen -ls

6. 进程管理最佳实践

6.1 进程监控建议

  1. 定期检查系统负载: 使用wuptime查看系统负载
  2. 监控关键进程: 使用pstop监控重要服务进程
  3. 设置进程监控: 使用监控工具(如Zabbix、Prometheus)监控进程状态
  4. 日志记录: 记录进程启动、停止和异常情况

6.2 进程终止建议

  1. 优先使用TERM信号: 给进程机会清理资源
  2. 谨慎使用KILL信号: 可能导致数据丢失
  3. 检查进程状态: 终止前使用ps检查进程状态
  4. 验证终止结果: 终止后验证进程是否真正退出

6.3 后台进程建议

  1. 使用nohup: 长时间运行的任务使用nohup
  2. 重定向输出: 后台进程的输出重定向到日志文件
  3. 使用screen/tmux: 需要交互的后台任务使用screen或tmux
  4. 记录PID: 记录后台进程的PID,方便后续管理

7. 命令总结

7.1 进程查看命令

命令 功能 示例
ps aux 查看所有进程 ps aux | grep nginx
ps auxf 查看进程树 ps auxf
ps axo 自定义显示字段 ps axo user,pid,%cpu
top 动态监控进程 top -d 1
pstree 显示进程树 pstree
pgrep 查找进程PID pgrep -l sshd
pidof 查找进程PID pidof sshd

7.2 进程控制命令

命令 功能 示例
kill PID 终止进程(TERM信号) kill 1234
kill -9 PID 强制终止进程 kill -9 1234
kill -1 PID 重新加载配置 kill -1 1234
killall name 终止所有同名进程 killall vim
pkill name 按名称终止进程 pkill -9 vim
pkill -t tty 终止指定终端进程 pkill -t pts/0

7.3 后台进程命令

命令 功能 示例
command & 后台运行 sleep 100 &
jobs 查看后台作业 jobs
bg %n 后台运行作业 bg %1
fg %n 前台运行作业 fg %1
kill %n 终止作业 kill %1
nohup command & 后台运行(不挂断) nohup command &