学习Linux——进程管理
《进程管理》2025年11月5日
一、进程基础概念
1.进程与程序的区别
程序:静态的指令合集(如/bin/ls/文件),不占用系统资源。
进程:动态的运行实例,拥有独立的地址空间、PID、寄存器状态等,是资源分配的最小单位。
线程:进程内的执行单元,共享进程资源,是CPU调度的最小单位(Linux中线程本质是“轻量级进程”)。
2.进程状态
在使用ps aux命令时,STAT列的状态含义:
R(运行态):正在占用CPU,或等待CPU调度(就绪态也归为R)
S(可中断睡眠):等待资源(如IO、信号),无法被信号唤醒
D(不可中断睡眠):等待硬件资源(如磁盘IO),无法被信号唤醒,强行中断可能导致数据丢失
T(停止态):被信号暂停(如Ctrl+Z,kill -19,需kill -18恢复
Z(僵尸态):进程已终止,但PCB(进程控制块)未被父进程收回,导致占用PID资源
<(高优先级):如R<,表示进程优先级高于普通进程
N(低优先级):如RN,表示进程优先级低于普通进程
+(前台进程组):如S+,表示进程在前台运行,终端关闭会收到 SIGHUP 信号
3.进程ID(PID)核心规则
PID是唯一标识进程的数字(1~32767,可通过/proc/sys/kernel/pid_max修改上限
1号进程:系统初始化进程,所有进程的“祖先”
PPID:父进程ID,通过ps -ef可查看父子进程关系
进程组 ID(PGID):多个进程组成一个组,方便批量管理(如kill -TERM -PGID终止整个进程组)
父进程与子进程:进程通过 fork () 创建子进程,子进程结束后需父进程回收资源,否则变为僵尸进程
二、管理进程命令
1.查看进程
(1)静态查看ps:
命令语法:ps [选项] -筛选条件
选项可分为 Unix 风格(带短横线 -)、BSD 风格(不带短横线) 和 GNU 风格(带双横线 --),实际使用中可混合搭配。
风格:
ps默认输出:
[root@haha ~]# ps | tail -5PID TTY TIME CMD1947 pts/0 00:00:00 bash2355 pts/0 00:00:00 vim
PID:进程唯一标识(最重要的字段)。
TTY:进程关联的终端(pts/0 表示虚拟终端)。
TIME:进程累计占用的 CPU 时间。
CMD:启动进程的命令。
ps aux(BSD 风格,最常用):
[root@haha ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.8 108428 16672 ? Ss 08:03 0:05 /usr/lib/systemd/systemd
root 2 0.0 0.0 0 0 ? S 08:03 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 08:03 0:00 [pool_workqueue_]
USER:进程所属用户。
PID:进程 ID。
%CPU:进程占用的 CPU 百分比。
%MEM:进程占用的内存百分比。
VSZ:虚拟内存大小(单位:KB)。
RSS:实际使用的物理内存大小(单位:KB)。
STAT:进程状态(如 R 运行、S 睡眠、Z 僵尸等)。
START:进程启动时间。
TIME:累计 CPU 时间。
COMMAND:完整的启动命令(包括参数)。
ps -ef(Unix 风格):
[root@haha ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:03 ? 00:00:05 /usr/lib/systemd/systemd --switched-roo
root 2 0 0 08:03 ? 00:00:00 [kthreadd]
root 3 2 0 08:03 ? 00:00:00 [pool_workqueue_]
UID:进程所属用户的用户 ID,
PID:进程唯一标识(Process ID),1 是系统中第一个启动的进程(通常是 systemd 或 init),2 是其相关进程。
PPID:父进程 ID(Parent Process ID),表示该进程由哪个进程创建
C:进程的 CPU 使用率(以整数形式表示,单位为百分比的近似值)
STIME:进程的启动时间
TTY:进程关联的终端,? 表示该进程不与任何终端关联,属于系统守护进程类。
TIME:进程累计占用的 CPU 时间
CMD:启动进程的完整命令(包括参数)
筛选进程:
-P <PID>:按PID筛选,查看指定进程
[root@haha ~]# ps -p 1PID TTY TIME CMD1 ? 00:00:06 systemd
-u <用户名> 或 --user < 用户名 >:按用户筛选
[root@haha ~]# ps -u root | head -2PID TTY TIME CMD1 ? 00:00:06 systemd
-C <命令名>:按进程名筛选(精确匹配命令名)
[root@haha ~]# ps -C httpdPID TTY TIME CMD983 ? 00:00:02 httpd1003 ? 00:00:00 httpd1004 ? 00:00:09 httpd# 查看所有 httpd 进程
-ejH 或 axjf:以树状结构显示进程的父子关系(方便查看进程间的调用链):
[root@haha ~]# ps -ejh994 1252 1252 1252 tty1 1252 Ss+ 0 0:00 -bash PATH=/usr/local/sb1946 1947 1947 1947 pts/0 2674 Ss 0 0:00 -bash USER=root LOGNAME=1947 2355 2355 1947 pts/0 2674 T 0 0:00 vim /etc/httpd/conf/http1947 2674 2674 1947 pts/0 2674 R+ 0 0:00 ps -ejh SHELL=/bin/bash[root@haha ~]# ps axjfPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND0 2 0 0 ? -1 S 0 0:00 [kthreadd]2 3 0 0 ? -1 S 0 0:00 \_ [pool_workqueue_]2 4 0 0 ? -1 I< 0 0:00 \_ [kworker/R-rcu_g]2 5 0 0 ? -1 I< 0 0:00 \_ [kworker/R-sync_]
结合 watch 命令:动态刷新进程信息 ps 是静态命令(只显示执行瞬间的状态),若需动态监控
watch -n 1 'ps aux' # 每秒刷新一次所有进程信息(ps 是静态命令,结合 watch 实现动态监控)
常用组合选项
ps aux --sort=-%cpu:按 CPU 占用率从高到低排序,同理:+从低到高排序。
[root@haha ~]# ps aux --sort=-%cpu | head -3
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2697 0.5 0.0 0 0 ? I 17:38 0:00 [kworker/1:0-events]
root 2655 0.4 0.0 0 0 ? I 17:32 0:01 [kworker/1:1-events]
[root@haha ~]# ps aux --sort=+%cpu | tail -2
root 2655 0.4 0.0 0 0 ? I 17:32 0:01 [kworker/1:1-events]
root 2697 0.5 0.0 0 0 ? I 17:38 0:00 [kworker/1:0-events]
ps aux --sort=-%mem:按内存占用率从高到低排序,同理:+从低到高排序。ps aux | grep <关键词>:结合grep搜索包含关键词的进程(如ps aux | grep python)。
(2)动态查看top:
top 是 Linux/Unix 系统中实时监控进程动态的核心命令,能够实时显示系统的 CPU、内存使用情况以及进程的资源占用,默认每 3 秒刷新一次,是排查系统性能问题的常用工具。
直接输入 top 命令即可启动实时监控界面:
界面分为两部分:
- 系统整体状态区(前几行,显示系统汇总信息)。
- 进程列表区(下方,按资源占用排序的进程详情)
[root@bogon ~]# top
top - 20:23:17 up 3 days, 10:09, 3 users, load average: 0.00, 0.05, 0.10
# 当前时间 系统运行时长 登录用户数 系统负载:1min内 5min内 15min内
Tasks: 233 total, 1 running, 232 sleeping, 0 stopped, 0 zombie
# 总进程数 运行数量 休眠数量 刚停止任务 僵尸进程
#任务: 233个任务 1个在运行(取决于你的CPU数)
%Cpu(s): 0.0 us, 0.5 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.2 hi, 0.0 si, 0.0 st
#cpu使用情况 用户空间 系统空间 空闲值
MiB Mem : 1930.5 total, 1179.4 free, 554.3 used, 389.5 buff/cache
MiB Swap: 2060.0 total, 2060.0 free, 0.0 used. 1376.2 avail Mem
# 用户 优先级 状态 进程的启动命令 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 863 root 20 0 242156 9212 7548 S 0.3 0.5 6:15.21 vmtoolsd 10228 root 20 0 20024 6792 4992 S 0.3 0.3 0:00.06 sshd 10271 root 20 0 0 0 0 I 0.3 0.0 0:06.06 kworker/0:2+10316 root 20 0 10612 4352 3456 R 0.3 0.2 0:00.23 top 1 root 20 0 173536 16364 11000 S 0.0 0.8 0:07.92 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.17 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.00 pool_workqu+4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/R-r+5 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/R-s+
系统整体状态区详解:
- 第一行:系统基本信息
10:23:45:当前系统时间。up 2 days, 3:45:系统运行时长(已开机 2 天 3 小时 45 分钟)。2 users:当前登录的用户数。load average: 0.30, 0.25, 0.20:系统 1 分钟、5 分钟、15 分钟的平均负载(数值越低,系统越空闲;超过 CPU 核心数可能表示负载过高)。
- 第二行:进程汇总
189 total:总进程数。1 running:正在运行的进程数。188 sleeping:睡眠的进程数。0 stopped:暂停的进程数。0 zombie:僵尸进程数(需关注,非 0 可能有问题)。
- 第三行:CPU 使用率(% Cpu (s))
us(user):用户态进程占用 CPU 百分比(如应用程序)。sy(system):内核态进程占用 CPU 百分比(如系统调用)。ni(nice):高优先级(调整过 nice 值)进程占用 CPU 百分比。id(idle):CPU 空闲百分比(越低表示 CPU 越繁忙)。wa(iowait):CPU 等待 I/O 操作的时间百分比(过高可能是磁盘 / 网络瓶颈)。hi(hardware irq):硬件中断占用 CPU 百分比。si(software irq):软件中断占用 CPU 百分比。st(steal):被虚拟机 hypervisor 占用的 CPU 百分比(仅虚拟机中有效)。
- 第四行:物理内存(Mem)
total:总物理内存大小。free:完全空闲的内存(未被使用)。used:已使用的内存(包括进程占用、缓存等)。buff/cache:用于缓存文件数据的内存(可被释放给其他进程使用)。
- 第五行:交换分区(Swap)
total:总交换分区大小。free:空闲交换分区。used:已使用的交换分区(频繁使用可能表示物理内存不足)。avail Mem:可被新进程使用的内存(约等于 free + 可释放的 buff/cache)。
进程列表区字段详解
默认按 CPU 使用率(%CPU)降序排列,主要字段:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND1234 root 20 0 123456 78900 45600 S 5.0 1.0 2:30.15 nginx5678 www-data 20 0 987654 123456 87600 R 10.0 1.5 5:45.30 php-fpm
PID:进程 ID。USER:进程所属用户。PR:进程优先级(数值越小优先级越高,-20最高,19最低)。NI:nice 值(调整优先级的参数,-20到19,与PR关系:PR = PR(base) + NI)。VIRT:进程使用的虚拟内存总量(包括未使用的)。RES:进程使用的物理内存(不包括交换分区)。SHR:进程与其他进程共享的内存大小。S:进程状态(同ps命令:R运行、S睡眠、Z僵尸等)。%CPU:进程占用 CPU 的百分比(自上次刷新以来)。%MEM:进程占用物理内存的百分比。TIME+:进程累计占用的 CPU 时间(精确到毫秒)。COMMAND:进程的启动命令。
常用交互操作(在 top 界面中输入)
- 排序:
P:按%CPU降序(默认)。M:按%MEM降序。N:按PID升序。T:按TIME+(累计 CPU 时间)降序。
- 筛选 / 搜索:
u:输入用户名,只显示该用户的进程(如u root只看 root 进程)。k:输入 PID,终止指定进程(需确认信号,默认15正常终止,9强制终止)。/:输入关键词,搜索进程命令(按n切换下一个结果)。
- 刷新与退出:
s:修改刷新间隔(如输入1表示每秒刷新一次)。q:退出 top 命令。
- 其他:
H:切换显示线程(默认显示进程,按H后显示进程内的线程)。1(数字 1):显示每个 CPU 核心的使用率(多核心系统中常用)。b:高亮显示当前排序的列。
(3)其他查看工具
htop:top的增强版,支持鼠标操作、颜色区分状态,需手动安装(yum install htop -y)。pgrep:快速查找进程 PID →pgrep nginx(直接输出 nginx 的所有 PID)。pidof:根据进程名查 PID →pidof nginx(效果同pgrep,更简洁)。
2.创建进程
创建进程的本质:从命令到运行实例
当你在终端输入一个命令(如ls),Linux会经历三个核心步骤创建进程:
解析命令:终端会识别命令路径(通过$PATH环境变量查找,比如ls对应/bin/ls)
系统调用:终端进程通过fork()复制自身,创建一个“子进程“(继承父进程的资源,如环境变量、文件描述符)
加载程序:子进程通过execve()系统调用,用新命令的代码和数据替换自身的内存空间,最终运行新程序
执行一次命令就是一次“复制父进程->替换为新程序”的过程
创建进程的三种常用方式
1.前台进程(默认):占用当前终端,执行时无法输入其他命令,终端关闭时会直接终止进程
使用场景:临时执行的短命令(ls、cd),实时交互的程序(python的交互解释器)
终止方式crtl + c(发送SIGINT信号,请求进程退出)
2.后台进程(&符号):不占用终端,执行时可继续输入其他命令,但终端关闭(如退出SSH)会终止进程
使用场景:耗时但无需交互的任务(批量处理文件、日志分析),需要临时放在后台运行
# 后台运行脚本,终端立即返回提示符,可继续操作
python long_task.py &
[1] 12345 # 输出:[后台进程编号] 进程PID
关键操作:
- 查看后台进程:
jobs(显示编号、状态、命令,如[1]+ Running python long_task.py &) - 调回前台:
fg %进程编号(如fg %1,将编号 1 的后台进程拉回前台,此时可按Ctrl+C终止) - 暂停后台进程:先
fg调回前台,再按Ctrl+Z(发送SIGTSTP信号,进程进入 “停止态 T”) - 恢复后台运行:
bg %进程编号(如bg %1,将停止的进程在后台恢复运行
3.长期后台进程(脱离终端,永久运行)
- 问题:用
&后台运行的进程,依赖当前终端的 “会话”,终端关闭(发送SIGHUP信号)会导致进程终止。 - 解决:让进程脱离终端控制,忽略
SIGHUP信号,适合服务类程序(如 Web 服务、爬虫)。 - 常用工具:
| 方法 | 命令示例 | 核心作用 | 适用场景 |
|---|---|---|---|
nohup | nohup python server.py & | 忽略 SIGHUP 信号,输出写入 nohup.out | 简单场景,临时后台服务 |
setsid | setsid python server.py | 创建独立会话,完全脱离终端 | 比 nohup 更彻底的后台运行 |
screen/tmux | screen -S mytask → 执行命令 → Ctrl+A+D | 创建虚拟终端,断开连接后进程仍在虚拟终端运行 | 需要长期维护的交互式任务 |
-
细节说明:
-
nohup输出重定向:默认日志写nohup.out,可自定义路径:nohup python server.py > /var/log/server.log 2>&1 & # 2>&1:将错误输出(stderr)合并到标准输出(stdout),一起写入日志文件 -
screen恢复会话:关闭终端后,重新连接服务器,用screen -r mytask回到之前的虚拟终端,进程仍在运行。
-
4.进程创建的特殊场景:父子进程关系
当一个进程(父进程)创建另一个进程(子进程),两者会形成 “依赖关系”:
- 子进程默认继承父进程的环境变量(如
$PATH)、工作目录、打开的文件等。 - 父进程终止后,子进程会被 “领养” 给 1 号进程(
systemd),避免成为 “孤儿进程”。 - 示例:用
bash终端(父进程 PID 1000)运行python test.py &,则:bash是父进程(PPID=1000),python是子进程(PID=12345,PPID=1000)。- 若关闭
bash终端(父进程终止),python进程会被 1 号进程领养(PPID 变为 1)。
如何选择创建方式?
| 需求场景 | 推荐方法 | 核心命令示例 |
|---|---|---|
| 临时执行,需要实时看输出 | 前台进程 | python test.py前台运行 test.py脚本,占用终端,需实时交互或短任务时用 |
| 临时后台运行,终端可继续用 | & 符号 | python task.py & + jobs/fg后台运行 task.py,用jobs查后台进程,fg可将其调回前台 |
| 关闭终端后仍运行(短期) | nohup + & | nohup python server.py > log &让 server.py长期后台运行,忽略终端关闭信号,输出存log |
| 长期运行,需要随时恢复交互 | screen/tmux | screen -S task → 执行命令 → detach用 screen创建虚拟终端运行命令,分离后进程仍长期后台运行,执行 screen -r task可随时恢复会话 |
3.控制进程
kill 命令是 Linux/Unix 系统中用于向进程发送信号以控制进程行为(如终止、暂停、重启)的工具,核心作用是通过信号与进程通信,而非直接 “杀死” 进程
语法:kill [选项] <PID> [PID...]
常用信号编号及名称
1 SIGHUP:挂起信号,常用与让进程重新加载配置(如nginx重载配置)2 SIGINT:中断信号,等价于终端中按Ctrl+C,用于终止前台进程3 SIGQUIT:退出信号,会生成核心转储(core dump),用于调试9 SIGKILL强制终止信号,进程无法补货或忽略,用于强制杀死无响应的进程15 SIGTERM:终止信号(默认),进程可捕获并执行清理操作后退出18 SIGCONT:继续信号,用于恢复被暂停(SIGSTOP)的进程19 SIGSTOP:暂停信号,用于暂停前台进程
常用操作示例
- 发送默认信号(
SIGTERM,编号15)
kill 1234 # 向 PID 为 1234 的进程发送 SIGTERM,请求优雅退出
- 强制终止进程(
SIGKILL,编号9)
kill -9 1234 # 强制杀死 PID 为 1234 的进程,无清理操作
- 重载进程配置(
SIGHUP,编号1)
kill -1 5678 # 让 PID 为 5678 的 nginx 进程重载配置
- 暂停 / 恢复进程
kill -19 9012 # 暂停 PID 为 9012 的进程(等价于 Ctrl+Z)
kill -18 9012 # 恢复被暂停的 PID 为 9012 的进程
- 批量操作(结合
ps筛选)
# 杀死所有包含 "python" 的进程(先筛选 PID 再批量 kill)
kill $(ps aux | grep python | grep -v grep | awk '{print $2}')
扩展命令
killall:按进程名而非 PID 发送信号(如killall nginx杀死所有 nginx 进程)。pkill:通过正则表达式匹配进程名发送信号(如pkill -9 python强制杀死所有 python 进程)。
优先级调整
- nice 值范围:-20(最高优先级)~19(最低优先级),默认 0。
- 普通用户只能提高 nice 值(降低优先级),root 用户可任意调整。
- 命令补充:
nice -n -5 ./test.sh:以 nice 值 - 5 创建进程(高优先级)。renice -10 1234:将 PID 为 1234 的进程 nice 值改为 - 10(提升优先级)。- 查看 nice 值:
ps -o pid,ni,cmd 1234(NI 列即为 nice 值)。
注意事项
- 权限限制:普通用户只能杀死自己拥有的进程;
root用户可杀死任意进程。 - 信号优先级:
SIGKILL(-9)无法被进程忽略,是最后的强制手段;优先使用SIGTERM(默认)让进程退出。 - 僵尸进程:若进程已成为僵尸进程(
STAT为Z),kill -9无效,需杀死其父进程或重启系统。
三常见问题及解决
1. 进程占用端口排查
问题:启动服务提示 “端口被占用” → 用lsof或netstat查找占用进程。
#查找占用端口
[root@haha yum.repos.d]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 983 root 4u IPv6 27154 0t0 TCP *:http (LISTEN)
httpd 1004 apache 4u IPv6 27154 0t0 TCP *:http (LISTEN)
httpd 1005 apache 4u IPv6 27154 0t0 TCP *:http (LISTEN)
httpd 1006 apache 4u IPv6 27154 0t0 TCP *:http (LISTEN)
[root@haha yum.repos.d]# netstat -tulnp | grep :80
tcp6 0 0 :::80 :::* LISTEN 983/httpd
#结束占用进程
[root@haha yum.repos.d]# kill -9 983
2. 高 CPU / 内存进程排查
- 高 CPU:
top按 “P” 排序,找到 PID → 用ps -ef | grep PID查看进程详情 → 若为异常进程,直接kill -9。 - 高内存:
top按 “M” 排序 → 若为正常服务(如 Java),可通过renice调整优先级,或优化服务配置(如 JVM 参数)。
3. 进程日志查看(关联进程管理)
- 查看进程的标准输出:
tail -f /proc/PID/fd/1(1 是 stdout,2 是 stderr)。 - 示例:实时查看 PID 为 1234 的进程日志 →
tail -f /proc/1234/fd/1。
