Linux进程管理


一、进程:程序的“动态运行形态”

1. 一句话理解进程

程序 是保存在硬盘或光盘等介质中的可执行代码和数据,是静态保存的代码。

进程 = 正在运行的程序。比如你打开一个终端(程序),这个终端在内存中运行的状态就是一个“进程”。每个进程都有自己的“身份证号”叫 PID(进程ID),系统靠它管理所有任务。

2. 程序 vs 进程(关键区别)

程序 进程
静态文件(存在硬盘,如/usr/bin/bash 程序的一次运行实例(加载到内存中执行)
不占用系统资源 占用CPU、内存、文件等资源
可以长期存在 有生命周期(启动→运行→结束)

3. 进程的“三大要素”(初学者必知)

  • PID:唯一标识进程(用 ps 命令查看)。
  • 状态:当前是“运行中”“暂停”还是“等待资源”(如等键盘输入)。
  • 资源:占用的CPU时间、内存、打开的文件(如浏览器进程会打开多个网页文件)。

二、进程状态:搞懂这5种就够用

ps aux 命令看到的 STAT 列表示进程状态,初学者重点记这5种:

状态 符号 含义(人话版) 例子
运行 R 正在使用CPU或排队等待CPU top命令时,top进程自身就是R状态
睡眠 S 暂时“休息”,等待外部信号(如键盘输入、网络数据) 终端里运行sleep 10,进程会处于S状态
暂停 T 被人为暂停(如按Ctrl+Z)或被调试器监控 vim编辑时按Ctrl+Z,进程变为T状态
僵尸 Z 进程已结束,但“爸爸进程”没回收资源(需手动处理) 父进程崩溃后,子进程可能变成僵尸
停止 X 进程彻底结束(状态一闪而过,很少看到) 关闭程序后,进程进入X状态并销毁

三、查看进程:3个核心命令(附超详细用法)

1. ps:给进程拍“快照”(静态查看)

ps aux  # 查看所有进程(包括其他用户的)

输出关键列解释(必背!)

  • USER:哪个用户启动的进程(如root是管理员,普通用户是你的用户名)。
  • PID:进程ID(唯一编号,杀进程时要用)。
  • %CPU:CPU占用率(越高越“耗电”,超过100%可能是多线程进程)。
  • %MEM:内存占用率(过高可能导致系统卡顿)。
  • COMMAND:启动进程的命令(如firefox表示火狐浏览器进程)。

2. top:动态监控进程(实时版“任务管理器”)

top  # 打开后实时显示进程状态,按q退出

常用操作(记这3个按键)

  • P:按CPU占用从高到低排序(找最“吃CPU”的进程)。
  • M:按内存占用从高到低排序(找最“吃内存”的进程)。
  • k:输入进程PID杀死该进程(强制终止用kill -9 PID)。

3. pgrep:快速搜索进程(按名称找PID)

pgrep firefox  # 直接输出火狐浏览器的所有PID
pgrep -l firefox  # 同时显示进程名和PID(更直观)

四、管理进程:启动、暂停、终止全攻略

1. 启动进程:前台 vs 后台

  • 前台进程:占用当前终端,必须等它结束才能输入新命令(如vim test.txt)。
  • 后台进程:加 & 符号,不占用终端(如下载文件):
wget https://example.com/bigfile.iso &  # 后台下载,终端可继续用

输出 [1] 12345[1]是任务编号,12345是PID。

2. 暂停/恢复进程

  • 暂停前台进程:按 Ctrl+Z(进程状态变为T,回到终端)。
  • 查看后台任务
jobs  # 显示所有后台任务(包括暂停的)
# 输出示例:[1]-  已停止               vim test.txt
  • 恢复后台运行
bg %1  # 让任务1在后台继续运行(%1是任务编号)
fg %1  # 把任务1调回前台,继续交互(如恢复`vim`编辑)

3. 终止进程:温和杀 vs 暴力杀

  • 温和终止(推荐)
kill PID  # 通知进程“你该结束了”(进程会先保存数据再退出)
  • 暴力终止(对付卡死进程)
kill -9 PID  # 强制杀死进程(不保存数据,可能导致数据丢失)
  • 按程序名批量杀(如关闭所有火狐进程):
killall firefox

五、父子进程:进程的“家族关系”

1. 什么是父子进程?

  • 父进程:创建其他进程的“爸爸进程”(如你打开终端bash,它就是父进程)。
  • 子进程:被父进程创建的“宝宝进程”(如在终端里运行toptop就是子进程)。

2. 查看进程家族树

pstree  # 直观显示进程父子关系(像家谱图)
# 输出示例:
# systemd(1)─┬─bash(1000)─┬─top(2000)
#            └─sshd(916)
  • systemd(PID=1)是所有进程的“祖先”,开机时第一个启动的进程。

3. 僵尸进程(初学者需警惕!)

  • 现象:进程已结束,但父进程没回收资源,状态显示为Z(僵尸)。
  • 危害:长期存在会占用PID资源,导致系统异常。
  • 处理:找到父进程并杀死(僵尸进程会被systemd自动回收):
ps aux | grep Z  # 查找僵尸进程
kill -9 父进程PID  # 终止父进程,僵尸进程会被init进程接管

六、守护进程:默默工作的“后台服务”

1. 什么是守护进程?

  • 特点:开机自动启动,长期运行在后台,无终端界面(如系统服务)。
  • 常见例子
  • sshd:允许远程连接(用ssh命令连服务器靠它)。
  • httpd/nginx:Web服务器,负责响应网页请求。
  • docker:Docker服务,管理容器运行。

2. 服务的概念

linux系统的服务(service)本质是一种运行在后台的进程,监听某个端口,等待其他应用的请求。 例如,sshd服务监听22端口,mysql服务监听3306端口,tomcat服务监听8080端口等。另一台电脑的终端可以通过22端口连接linux服务器的sshd服务,navicat可以3306端口连接服务器的mysql服务,浏览器可以通过8080端口连接服务器的tomcat服务。

3. 管理守护进程(以sshd为例)

systemctl status sshd  # 查看服务状态(是否运行)
systemctl start sshd   # 启动服务
systemctl stop sshd    # 停止服务
systemctl enable sshd  # 设置开机自启
systemctl disable sshd # 关闭开机自启

七、初学者常见问题与解决

1. 误杀系统进程怎么办?

  • 后果:杀死systemd(PID=1)等核心进程会导致系统崩溃!
  • 预防:杀进程前先用 ps aux | grep PID 确认进程用途,避免杀root用户的关键进程。

2. 进程占用内存过高怎么办?

  1. topM排序,找到高内存进程的PID。
  2. 确认是否正常程序(如浏览器开了100个标签页),若异常则kill -9 PID
  3. 长期内存不足需增加物理内存或配置Swap分区。

3. 命令卡住不动怎么办?

  • Ctrl+C:终止前台运行的命令(如curl下载失败时)。
  • Ctrl+Z:暂停命令,用 jobs 查看后再kill对应的任务。

八、必背口诀与总结

1. 口诀速记

  • 进程是“运行的程序”,PID是身份证,ps aux看状态,top实时查资源。
  • 后台任务加&,暂停就按Ctrl+Zjobs列表bg/fg调,杀进程用kill PID
  • 守护进程是“后台服务”,systemctl命令管启停,僵尸进程找父进程,暴力终止加-9

2. 学习路线建议

  1. 先掌握pstopkill三个核心命令,能熟练查看和终止进程。
  2. 理解进程状态(R/S/T/Z)的含义,学会区分前台/后台任务。
  3. 进阶学习守护进程管理(systemd)和简单的性能分析(如内存/CPU占用排查)。

命令与案例

ps命令

用途:查看静态的进程统计信息

格式

ps aux

[root@zuolaoshi ~]# ps    #静态进程管理命令,可以帮助我们查看到ps命令在执行那一刻后台进程的状态
-A          所有进程,等同于-ax
-a          显示所有进程(与终端有关的除外)
-x          与参数a一起使用等同于-A
-u          显示指定用户的进程
-l          长格式
-f          完整输出
-t          从指定终端启动的进程
-C          执行指定命令的进程
[root@zuolaoshi ~]# ps aux      #查看系统后台的所有进程
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1 252828 11580 ?        Ss   10月23   0:04 /us...
root          2  0.0  0.0      0     0 ?        S    10月23   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        I<   10月23   0:00 [rcu_gp]
root          4  0.0  0.0      0     0 ?        I<   10月23   0:00 [rcu_par_gp]
root          6  0.0  0.0      0     0 ?        I<   10月23   0:00 [kworker/0:0H-kblockd]
root          8  0.0  0.0      0     0 ?        I<   10月23   0:00 [mm_percpu_wq]
root          9  0.0  0.0      0     0 ?        S    10月23   0:00 [ksoftirqd/0]


USER            开启进程的用户
PID             进程的识别号
%CPU            进程的cpu占用率
%MEM            进程的物理内存占用率
VSZ             虚拟内存用量,单位Kbytes
RSS             物理内存占用量 Kbytes
TTY             那个终端开启的
STAT            进程的状态
START           开启时间
TIME            CPU占用时间
COMMAND         执行具体内容

[root@zuolaoshi ~]# ps -l       查看当前用户开启的进程
F S  UID    PID  PPID  C PRI  NI ADDR SZ WCHAN      TTY    TIME     CMD
0 S   0   5191   5189  0  80   0    -  6994 -      pts/1 00:00:02 bash
0 R   0  14972   5191  0  80   0    - 11240 -      pts/1 00:00:00 ps

F   进程标识
    0=没有被设置
    1=从父进程派生出来但是没有执行
    4=权限为root
    5=1+4

S   进程状态
    R=运行
    S=睡眠,可被唤醒
    D=睡眠,不可被唤醒(资源不足引起)
    T=停止
    Z=僵尸进程

UID 用户识别号
PID 进程识别号
PPID    父进程号
C   cpu使用率 %
PRI     内核调度优先级
NI      用户设置优先级
ADDR    加载到内存的位置,如果是运行的会用-表示
SZ      用掉的内存页的大小,1个内存页=4096Bytes 也就是6994x4=27976K内存
WCHAN   当前进程在哪个内核函数上睡眠,-表示正在运行,没有睡眠
TTY     由哪个终端开启的    pts/n=图形界面或远程       ttyn=字符界面       ?=系统进程
TIME    用掉的CPU时间
CMD     执行的命令

ps只能显示它运行的那一刻的进程的统计信息,如果你想动态的查看就需要使用top

top动态查看

[root@zuolaoshi ~]# top
-d          指定两次刷新的时间间隔,默认是3秒
-p          后面跟进程号,查看指定进程的状态,最多20个PID
-n          刷新指定次数后退出
-b          批量模式,可以让top将内容输出到指定的位置
top的按键
?               显示帮助
空格&enter               刷新
E               切换统计信息部分,内存显示的单位
e               切换任务列表的内存显示的单位
l               显示或隐藏摘要信息中的负载统计(第一行内容)
t               切换显示或隐藏摘要信息中任务和CPU统计信息(第2,3行内容)
m               切换显示或隐藏摘要信息中内存统计(第4,5行内容)
u               查看指定用户的进程
M               根据内存排序
P               根据cpu排序
N               根据PID排序
R               反向排序
F/f         调整任务列表显示的内容,默认只有PID,USER,PR,NI....COMMAND等这些,可              以自定义还需要显示哪些内容,如果显示的列比较多可以使用</>进行左右移动
shift+</>按照下一列的内容排序,比如说当前按照PID排序如果按下shift+>,则按照用户名                  排序,再次按下就会按照PR排序,一次类推 
T               根据cpu使用时间排序
k               杀死进程
r               修改进程的nice值(优先级)
z               将不同的位置标记颜色
x               高亮显示排序字段
y               高亮显示正在运行的任务
b               将高亮显示部分加上背景色
Z               自定义颜色
L               搜索指定字段,&下一个
H               在进程和线程间切换显示和统计方式,默认为进程
V               树形显示统计信息
J               显示内容左对齐或右对齐
c               切换COMMAND列的显示形式,程序名/命令格式
i               显示或隐藏空闲进程
u/U         查看指定用户的进程
d               设置刷新间隔,默认3秒刷新一次
W               将当前的设置写入到~/.config/procps/toprc中
q               退出top
[root@zuolaoshi ~]# top -d 1
1 top - 18:57:05 up 12:56,  3 users,  load average: 0.00, 0.00, 0.00
2 Tasks: 280 total,   1 running, 279 sleeping,   0 stopped,   0 zombie
3 %Cpu(s): 1.5 us,1.5 sy,0.0 ni,97.0 id,0.0 wa,0.0 hi,0.0 si,0.0 st
4 MiB Mem : 3918.6 total, 160.1 free, 1264.5 used, 2494.0 buff/cache
5 MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 2356.6 avail Mem 
6
7PID USER  PR  NI VIRT    RES    SHR  S  %CPU  %MEM   TIME+  COMMAND  
 1   root  20  0  244408  13740  9100 S  0.0   0.3   0:08.77 systemd
 2   root  20  0  0       0      0    S  0.0   0.0   0:00.04 kthreadd  3   root  0  -20 0       0      0    I  0.0   0.0   0:00.00 rcu_gp    4   root  0  -20 0       0      0    I  0.0   0.0   0:00.00 cu_par_gp 

1-6行显示的内容为
1   当前时间为18:57:05;系统一共开机12小时56分;当前有3个用户登录;系统在1,5,15分钟的平均负载,越小表示系统越空闲

2   系统中进程的统计信息 总计280个,1个运行,279睡眠,0个停止,0个僵尸

3   cpu的负载  按键盘上的“1”可以按照CPU核心数显示
            us: 用户空间进程占用CPU时间百分比
            sy: 内核进程占用CPU时间百分比
            ni: 用户空间内改变过优先级的进程占用CPU时间百分比
            id: 空闲CPU时间百分比(100%表示系统完全空闲)
            wa: I/O等待占用的CPU时间百分比
            hi: 硬件中断占用CPU时间百分比
            si: 软件中断占用CPU时间百分比
            st: 虚拟化hypervisor从当前虚拟机偷走的时间(如果这个值很高的话,说明你的提                    供商的CPU资源有限,而你没能抢过别人,很有可能就是VPS提供商超售了.)
4&5 物理内存和虚拟内存相关的统计信息,尤其要注意swap,如果被大量占用,说明你物理内           存不足了
6   在top中输入命令时,会显示在这里
7   系统进程的信息
    PID:    进程ID 
    USER    进程所有者
    PR      进程优先级
    NI  nice值,负数表示高优先级,正数表示低优先级
    VIRT    虚拟内存使用量,单位为KB。
    RES    进程使用的、未被换出的物理内存大小,单位为KB。
    SHR     进程使用共享内存大小,单位为KB。
    S   进程状态
    %CPU    进程对CPU的使用率。
    %MEM   进程对内存的使用率
    TIME+  进程使用CPU时间总结,单位秒。
    COMMAND 命令

top显示的内容有些看不到怎么办?
[root@zuolaoshi ~]# top -b -n1 > /tmp/top.txt
有些时候想查看的进程资源占用很低,在top中显示的比较靠后,怎么办?
[root@zuolaoshi ~]# top -d 2 -p 3562
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.2 us,  3.9 sy,  0.0 ni, 93.3 id,  0.0 wa,  0.5 hi,  0.1 si,  0.0 st
MiB Mem : 3918.6 total, 1495.1 free, 1407.0 used, 1016.5 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used.   2258.4 avail Mem 

PID USER   PR  NI   VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND  
3562 root  20   0   49296   6380   4448 S   0.0   0.2   0:00.08 bash

上面所提到的两个查看系统进程的命令,静态的ps和动态的top,他们所显示的内容比较多,有的时候我只想查看一下进程之间的关系,这个时候我可以使用另外的一条命令

[root@zuolaoshi ~]# pstree
    A               进程之间使用ASCII字符连接
    U               进程之间使用UTF-8编码连接
    p               显示进程号
    u               显示用户

[root@zuolaoshi ~]# pstree -A | more
systemd-+-ModemManager---2*[{ModemManager}]
        |-NetworkManager---2*[{NetworkManager}]
        |-VGAuthService
        |-accounts-daemon---2*[{accounts-daemon}]
        |-alsactl
        |-atd
        |-auditd-+-sedispatch
        |        `-2*[{auditd}]
[root@zuolaoshi ~]# pstree -U | more
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─accounts-daemon───2*[{accounts-daemon}]
        ├─alsactl
        ├─atd
        ├─auditd─┬─sedispatch
        │        └─2*[{auditd}]

[root@zuolaoshi ~]# pstree -pu | more
systemd(1)-+-ModemManager(916)-+-{ModemManager}(943)
           |                   `-{ModemManager}(949)
           |-NetworkManager(1040)-+-{NetworkManager}(1050)
           |                      `-{NetworkManager}(1053)
           |-VGAuthService(902)
           |-accounts-daemon(1010)-+-{accounts-daemon}(1013)
           |                       `-{accounts-daemon}(1015)
           |-alsactl(909)
           |-atd(1076)
           |-auditd(862)-+-sedispatch(864)
           |             |-{auditd}(863)
           |             `-{auditd}(865)
           |-avahi-daemon(910,avahi)---avahi-daemon(953)

linux的工作调度

由于linux是一个多人多任务的操作系统,所以用户在使用linux的时候就会出现有些工作我们需要盯着完成的进度,而有些工作我们直接放在后台执行就可以了,这里面我们就涉及到任务的前后台执行的问题。

开启一个在后台执行的工作

[root@zuolaoshi ~]# cd /
[root@zuolaoshi /]# tar -czf /tmp/test.tar.gz etc & (&表示后台执行)
[1] 13568               [1]工作序号;13568进程号(PID)
[root@zuolaoshi /]# ls tmp/ | grep test
test.tar.gz

执行完成后,会在下次敲回车的时候给用户一个反馈
[1]+  已完成               tar -czpf /tmp/test.tar.gz etc

将当前的工作调到后台

[root@zuolaoshi /]# cd
[root@zuolaoshi ~]# ls
公共  视频  文档  音乐  anaconda-ks.cfg
模板  图片  下载  桌面  initial-setup-ks.cfg
[root@zuolaoshi ~]# vim anaconda-ks.cfg         按键盘上的ctrl+z是调到后台

[1]+  已停止               vim anaconda-ks.cfg     
注意由ctrl+z调到后台的工作状态为暂停

那么如何将后台工作的状态更改为运行?如何查看后台有哪些工作呢?

后台工作的查看及状态的更改

[root@zuolaoshi ~]# jobs     #查看后台工作
[1]-  已停止               vim anaconda-ks.cfg
[2]+  已停止               find / -print
[root@zuolaoshi ~]# jobs -l  #查看后台工作,并显示进程号
[1]- 13663 停止                  vim anaconda-ks.cfg
[2]+ 13732 停止                  find / -print
[root@zuolaoshi ~]# jobs -s  #仅查看状态为停止的后台工作
[1]-  已停止               vim anaconda-ks.cfg
[2]+  已停止               find / -print
[root@zuolaoshi ~]# jobs -r  #仅查看状态为运行的后台工作

+:  当使用命令将后台任务调到前台时,默认调用有此标记的任务,也就是最近被调到后台的
-:  倒数第二个被调到后台的任务


[root@zuolaoshi ~]# fg %工作序号(%可省略)  将后台指定的工作调到前台
[root@zuolaoshi ~]# find / -name \*a\* > /tmp/test.txt
^Z      执行一个命令,迅速使用ctrl+z将任务调到后台
[2]+  已停止               find / -name \*a\* > /tmp/test.txt
[root@zuolaoshi ~]# bg %2;jobs 连续执行两条命令,1.使用bg命令将之前的工作状态更改为运行;2.立即使用jobs命令查看状态
[2]+ find / -name \*a\* > /tmp/test.txt &
[1]+  已停止               vim anaconda-ks.cfg
[2]-  运行中               find / -name \*a\* > /tmp/test.txt &

注意:更改后台工作状态和查看后台工作状态的命令也可以在终端分别输入,但是如果命令执行的较快的话可能会出现下面的这种情况,也就是状态显示为已完成
[root@zuolaoshi ~]# find / -name \*a\* > /tmp/test.txt
^Z
[2]+  已停止               find / -name \*a\* > /tmp/test.txt
[root@zuolaoshi ~]# jobs
[1]-  已停止               vim anaconda-ks.cfg
[2]+  已停止               find / -name \*a\* > /tmp/test.txt
[root@zuolaoshi ~]# bg %2
[2]+ find / -name \*a\* > /tmp/test.txt &
[root@zuolaoshi ~]# jobs
[1]+  已停止               vim anaconda-ks.cfg
[2]-  已完成               find / -name \*a\* > /tmp/test.txt

kill 杀死进程

我们可以通过kill命令配合适当的信号来管理后台的工作。

[root@zuolaoshi ~]# kill PID
需要注意的是,kill后面如果加的是%num代表杀死后台指定序号的工作,如果不加%代表的是杀死指定进程号的进程,这两个是有区别的

[root@zuolaoshi ~]# kill %工作序号
        -l              查看
        -1              重新加载,systemctl reload servername
        -2              保存数据并结束 ctrl+c          
        -9              强制结束不管其状态       常用在无法正常终止的程序上
        -15             正常结束(默认值)       systemctl stop servername
[root@zuolaoshi ~]# jobs
[1]+  已停止               vim anaconda-ks.cfg
[root@zuolaoshi ~]# kill -9 %1
[1]+  已停止               vim anaconda-ks.cfg
[root@zuolaoshi ~]# jobs
[1]+  已杀死               vim anaconda-ks.cfg
[root@zuolaoshi ~]# jobs

# killall通过名称杀死进程
[root@zuolaoshi ~]# killall
    e       精确匹配,最多不能超过15个字符
    i       询问用户是否杀死指定名称的进程
    I       进程的名称忽略大小写
[root@zuolaoshi ~]# cat /dev/zero > /dev/null &
[1] 102245
[root@zuolaoshi ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S     0   3562   3559  0  80   0 - 12324 -      pts/1    00:00:00 bash
0 R     0 102245   3562 97  80   0 -  1908 -      pts/1    00:00:01 cat
0 R     0 102246   3562  0  80   0 - 11240 -      pts/1    00:00:00 ps
[root@zuolaoshi ~]# killall -ei cat
杀死 cat(102870) ? (y/N) y
[1]+  已终止               cat /dev/zero > /dev/null