Linux 进程管理详解

进程 是 Unix 和 Linux 系统中对正在运行中的应用程序的抽象,通过它可以管理和监视程序对内存、处理器时间和 I / O 资源的使用。

一、进程的组成

一个进程包含内核中的一部分地址空间和一系列数据结构。其中地址空间是内核标记的一部分内存以供进程使用,而数据结构则用来纪录每个进程的具体信息。

最主要的进程信息包括:

  • 进程的地址空间图
  • 进程当前的状态( sleeping、stopped、runnable 等)
  • 进程的执行优先级
  • 进程调用的资源信息
  • 进程打开的文件和网络端口信息
  • 进程的信号掩码(指明哪种信号被屏蔽)
  • 进程的属主
PID :进程 ID

每个进程都会从内核获取一个唯一的 ID 值。绝大多数用来操作进程的命令和系统调用,都需要用 PID 指定操作的进程对象。

PPID :父进程 ID

在 Unix 和 Linux 系统中,一个已经存在的进程必须“克隆”它自身来创建一个新的进程。当新的进程克隆后,最初的进程便作为父进程存在。

UID & EUID:真实用户 ID 和有效用户 ID

一个进程的 UID 是其创建者的身份标志(也是对其父进程 UID 的复制)。通常只有进程的创建者和超级用户才有操作该进程的权限。
EUID 是一个额外的 UID,用来决定在任意一个特定时间点,一个进程有权限访问的文件和资源。对绝大多数进程而言,UID 和 EUID 是相同的(特殊情况即 setuid)

Niceness

一个进程的计划优先级决定了它能获取到的 CPU 时间。内核有一个动态的算法来计算优先级,同时也会关注一个 Niceness 值,来决定程序运行的优先顺序。

二、信号

信号属于进程级别的中断请求。它们可以作为进程间通信的手段,或者由终端发送以杀死、中断、挂起某个进程。

常见信号列表:

# name Description Default Can catch? Can block? Dump core?
1 HUP Hangup Terminate Yes Yes No
2 INT Interrupt(Ctrl + C) Terminate Yes Yes No
3 Quit Quit(Ctrl + \) Terminate Yes Yes Yes
9 KILL Kill Terminate No No No
BUS Bus error Terminate Yes Yes Yes
11 SEGV Segmentation fault Terminate Yes Yes Yes
15 TERM Software terminatation Terminate Yes Yes No
STOP Stop(Ctrl + Z) Stop No No No
TSTP Keyboard stop Stop Yes Yes No
CONT Continue after stop Ignore Yes No No

三、Kill 命令

kill 命令常用来终止某个进程,它可以向进程传递任意信号(默认为 TERM)。
kill [-signal] pid
不带任何数字(信号)选项的 kill 命令并不能保证指定进程被杀死,因为 kill 命令默认发送 TERM 信号,而 TERM 是可以被捕获、屏蔽或忽略的。
可以使用 kill -9 pid 命令强制杀死进程(9 代表 KILL 信号,不可被捕获、屏蔽或忽略)。

kill 命令需要指定进程的 PID 号。
pgrep 命令可以通过程序名称(或其他属性如 UID)筛选进程号,pkill 命令可以直接发送指定信号给筛选结果。
sudo pkill -u ben
该命令将发送 TERM 信号给所有属于用户 ben 的进程。

killall 命令可以通过程序名称杀死指定进程的所有实例。如:
sudo killall apache2

$ pgrep postgres  # 筛选 postgres 进程的 PID 号 
25874
25876
25877
25878
25879
25880
25881
$ pgrep -a postgres  # 筛选 postgres 进程的 PID 号,并输出详细信息
25874 /usr/lib/postgresql/10/bin/postgres -D /var/lib/postgresql/10/main -c config_file=/etc/postgresql/10/main/postgresql.conf
25876 postgres: 10/main: checkpointer process
25877 postgres: 10/main: writer process
25878 postgres: 10/main: wal writer process
25879 postgres: 10/main: autovacuum launcher process
25880 postgres: 10/main: stats collector process
25881 postgres: 10/main: bgworker: logical replication launcher

$ sudo kill -9 `pgrep postgres`  # 杀死 postgres 进程
$ sudo pkill postgres  # 同上一条命令
$ sudo killall postgres  # 杀死 postgres 进程的所有实例
$ sudo pkill -9 -u postgres  # 杀死属于 postgres 用户的所有进程

根据进程 PID 号查找进程可以使用 ps -p <pid> -o comm= 命令

四、进程状态

状态 含义
Runnable 该进程正在(正准备)执行
Sleeping 该进程正等待某些资源
Zombie 该进程正努力尝试结束
Stopped 该进程已挂起(不允许执行)
  • Runnable 表示进程已经获取到了运行所需的所有资源,只是等待相应的 CPU 时间来处理数据。
  • Sleeping 表示进程处于等待特定事件发生的状态。交互式 Shell 和系统守护进程的大部分时间都是 Sleeping 状态,等待用户输入或网络连接。
  • Zombies 表示进程已经结束执行,但是还没有收集完所有的状态,在进程表中仍有纪录。
  • Stopped 表示进程已停止运行,通常是收到了某种停止信号。

五、PS 命令:监控资源

ps 命令是系统管理员监控进程的主要工具。该命令可以显示进程的 PID、UID、优先级和控制终端,以及进程占用的内存、消耗的 CPU 时间和当前的状态等信息。

常用的 PS 命令选项组合:

1. ps aux

a 选项表示显示所有进程,x 选项表示同时显示没有控制终端的进程(TTY 显示为 ?),u 选项表示使用基于用户的信息输出格式

$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 225428  9548 ?        Ss   7月30   0:30 /lib/systemd/systemd --system --deserialize 19
root         2  0.0  0.0      0     0 ?        S    7月30   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        I<   7月30   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        I<   7月30   0:00 [mm_percpu_wq]
root         7  0.0  0.0      0     0 ?        S    7月30   0:03 [ksoftirqd/0]
root         8  0.0  0.0      0     0 ?        I    7月30  14:49 [rcu_sched]
...
starky    6874  0.0  0.1  33016  8556 pts/2    Ss   8月07   0:00 bash
starky    7150  0.0  0.0  33016  6044 pts/2    S+   8月07   0:00 bash
starky    7151  3.1 16.1 4763784 1227932 pts/2 Sl+  8月07 272:54 java -Xmx1024M -Xms512M -jar minecraft_server.1.12.2.jar nogui
...
root     18447  0.0  0.0 107984  7116 ?        Ss   13:55   0:00 sshd: starky [priv]
starky   18535  0.0  0.0 108092  4268 ?        S    13:55   0:00 sshd: starky@pts/1
starky   18536  0.0  0.1  33096  8336 pts/1    Ss   13:55   0:00 -bash
root     18761  0.0  0.0      0     0 ?        I    13:55   0:00 [kworker/u8:0]
root     18799  0.0  0.0      0     0 ?        I    14:01   0:00 [kworker/u8:1]
root     18805  0.0  0.0      0     0 ?        I    14:05   0:00 [kworker/0:2]
starky   18874  0.0  0.0  46780  3568 pts/1    R+   14:10   0:00 ps -aux
redis    19235  0.2  0.0  58548  3736 ?        Ssl  8月04  30:03 /usr/bin/redis-server 127.0.0.1:6379
root     20799  0.0  0.0 107548  7504 ?        Ss   8月05   0:00 /usr/sbin/cupsd -l
root     28342  0.0  0.4 535068 36940 ?        Ss   8月10   0:16 /usr/sbin/apache2 -k start

其中带中括号的命令(如 [kthreadd])并不是真正的命令而是内核线程。

ps aux 命令输出的各列信息含义如下:

项目 解释
USER 进程属主的用户名
PID 进程 ID
%CPU 进程占用的 CPU 百分比
%MEM 进程使用的内存百分比
VSZ 进程的虚拟大小
RSS 驻留内存大小(内存中的页数)
TTY 控制终端 ID
STAT 进程当前的状态:

R = Runnable
D = In uninterruptible sleep
S = Sleeping(<20s)
T = Traced or stopped
Z = Zombie

额外标记:

W = Process is swapped out
< = 进程有相对于平时更高的优先级
N = 进程有相对于平时更低的优先级
L = Some pages are locked in core
s = Process is a session leader
TIME 进程已经消耗的 CPU 时间
COMMAND 进程的命令和命令选项
2. ps lax

l 选项表示以详细的格式输出进程信息。

$ ps lax
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
4     0     1     0  20   0 225428  9548 -      Ss   ?          0:30 /lib/systemd/systemd --system --deserialize 19
1     0     2     0  20   0      0     0 -      S    ?          0:00 [kthreadd]
1     0     4     2   0 -20      0     0 -      I<   ?          0:00 [kworker/0:0H]
1     0     6     2   0 -20      0     0 -      I<   ?          0:00 [mm_percpu_wq]
1     0     7     2  20   0      0     0 -      S    ?          0:03 [ksoftirqd/0]
1     0     8     2  20   0      0     0 -      I    ?         14:58 [rcu_sched]
...
0  1000  6874  6871  20   0  33016  8556 wait   Ss   pts/2      0:00 bash
1  1000  7150  6874  20   0  33016  6044 wait   S+   pts/2      0:00 bash
0  1000  7151  7150  20   0 4763784 1227932 futex_ Sl+ pts/2  275:03 java -Xmx1024M -Xms512M -jar minecraft_server.1.12.2.jar nogui
...
4     0 18447   619  20   0 107984  7116 -      Ss   ?          0:00 sshd: starky [priv]
5  1000 18535 18447  20   0 108092  4268 -      S    ?          0:00 sshd: starky@pts/1
0  1000 18536 18535  20   0  33096  8336 wait   Ss   pts/1      0:00 -bash
1     0 19051     2  20   0      0     0 -      I    ?          0:00 [kworker/3:0]
1     0 19141     2  20   0      0     0 -      I    ?          0:00 [kworker/2:3]
1   115 19235     1  20   0  58548  3736 -      Ssl  ?         30:22 /usr/bin/redis-server 127.0.0.1:6379
1     0 19246     2  20   0      0     0 -      I    ?          0:00 [kworker/2:0]
1     0 19291     2  20   0      0     0 -      I    ?          0:00 [kworker/u8:0]
1     0 19312     2  20   0      0     0 -      I    ?          0:00 [kworker/0:2]
1     0 19405     2  20   0      0     0 -      I    ?          0:00 [kworker/u8:1]
0  1000 19417 18536  20   0  36024  1596 -      R+   pts/1      0:00 ps -lax
4     0 20799     1  20   0 107548  7504 -      Ss   ?          0:00 /usr/sbin/cupsd -l
5     0 28342     1  20   0 535068 36940 -      Ss   ?          0:16 /usr/sbin/apache2 -k start

ps lax 命令的输出包含了父进程 ID(PPID)、nice 值(NI)还有进程正在等待的资源类型(WCHAN)等。

3. ps axjf

ps axjf 命令能够以树状结构显示各进程间的层级关系
f 选项表示用 ASCII 字符显示树状结构,表达程序间的相互关系。

$ ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     2     0     0 ?           -1 S        0   0:00 [kthreadd]
    2     4     0     0 ?           -1 I<       0   0:00  \_ [kworker/0:0H]
    2     6     0     0 ?           -1 I<       0   0:00  \_ [mm_percpu_wq]
    2     7     0     0 ?           -1 S        0   0:02  \_ [ksoftirqd/0]
    2     8     0     0 ?           -1 I        0   4:26  \_ [rcu_sched]
...
    1   672   672   672 ?           -1 Ss       0   0:00 /usr/sbin/sshd -D
  672 27078 27078 27078 ?           -1 Ss       0   0:00  \_ sshd: starky [priv]
27078 27166 27078 27078 ?           -1 S     1000   0:00      \_ sshd: starky@pts/1
27166 27167 27167 27167 pts/1    27438 Ss    1000   0:00          \_ -bash
27167 27438 27438 27167 pts/1    27438 R+    1000   0:00              \_ ps axjf
    1   681   681   681 ?           -1 Ssl    115   9:40 /usr/bin/redis-server 127.0.0.1:6379
    1   700   700   700 tty1       700 Ss+      0   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
    1   710   710   710 ?           -1 Ss       0   0:14 /usr/sbin/apache2 -k start
  710 25651   710   710 ?           -1 S       33   0:00  \_ /usr/sbin/apache2 -k start
  710 25652   710   710 ?           -1 S       33   0:00  \_ /usr/sbin/apache2 -k start
  710 25653   710   710 ?           -1 S       33   0:00  \_ /usr/sbin/apache2 -k start
  710 25654   710   710 ?           -1 S       33   0:00  \_ /usr/sbin/apache2 -k start
  710 25655   710   710 ?           -1 S       33   0:00  \_ /usr/sbin/apache2 -k start
  ...
4. ps o

ps o 命令加上选项可以指定信息的输出格式,同时加上 --sort 选项可指定排序依据
如:ps axo pid,ppid,%mem,%cpu,cmd --sort=-%mem
上面的命令表示输出进程的 PID、PPID、内存占用、CPU占用和命令选项。并以内存占用大小排序。(--sort=-%mem 中的 - 表示逆向排序,即由大到小排序)

$ ps axo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head
  PID  PPID %MEM %CPU CMD
 1790  1789 14.1  3.8 java -Xmx1024M -Xms512M -jar minecraft_server.1.12.2.jar nogui
 1357     1  2.6  0.1 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
 9343     1  2.0  0.0 /usr/bin/python3 /usr/bin/update-manager --no-update --no-focus-on-map
 1244     1  1.5  0.0 sogou-qimpanel %U
 1024     1  1.0  0.0 /usr/bin/fcitx
 1454     1  0.9  0.0 fcitx-qimpanel
 7401  1067  0.7  0.0 lxterminal
  248     1  0.6  0.0 /lib/systemd/systemd-journald
 1119     1  0.6  0.0 nm-applet

可以尝试不同的命令选项组合来获取相应的信息,具体可参考 man ps

六、使用 TOP 命令动态监控进程

top 命令可以实时显示系统当前活跃进程的总体信息及其占用的资源。

top

top 命令的 -d 选项可以指定信息刷新的时间间隔。同时还有一些常用的交互命令

命令 描述
h 显示帮助信息
k 终止某个进程
i 忽略闲置和僵死进程(这是一个开关式命令)
q 退出 top 程序
r 重新设置某个进程的优先级
s 改变两次刷新之间的延迟时间(单位为s)
f 或 F 从当前显示中添加或者删除项目
l 切换显示平均负载和启动时间信息
m 切换显示内存信息
t 切换显示进程和CPU状态信息
c 切换显示命令名称和完整命令
M 根据驻留内存大小进行排序
P 根据CPU使用百分比大小进行排序
T 根据时间/累计时间进行排序
w 将当前设置写入 ~/.toprc 文件中

七、前台/后台进程

  • 前台进程(也称作交互式进程):由某个终端会话创建和控制的进程。即需要用户控制而不能作为系统服务自动启动。
  • 后台进程(也称作非交互式进程):不和终端绑定的进程,不等待用户输入。

可以在命令后带上 & 符号,在后台启用一个 Linux 进程执行该命令。并通过 jobs 命令查看当前的任务。
使用 fg 命令将后台执行的进程调到前台执行
使用 Ctrl + Z 组合键(发送 SIGSTOP 信号)挂起当前进程(前台),并使用 bg 命令令其在后台继续执行

$ python -m SimpleHTTPServer &  # 后台启动 python 进程
[1] 28036
$ Serving HTTP on 0.0.0.0 port 8000 ...

$ jobs                          # 使用 jobs 命令查看后台进行的任务
[1]+  运行中               python -m SimpleHTTPServer &
$ fg %1                         # 将后台执行的第一个任务调到前台执行(fg %1)
python -m SimpleHTTPServer
^Z                              # 使用 Ctrl + Z 组合键(发送 STOP 信号)停止当前进程
[1]+  已停止               python -m SimpleHTTPServer
$ bg                            # 使用 bg 命令将进程调至后台继续执行
[1]+ python -m SimpleHTTPServer &
$ fg %1
python -m SimpleHTTPServer

参考资料

UNIX and Linux System Administration Handbook, 4th Edition
All You Need To Know About Processes in Linux

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容

  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,033评论 9 467
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,113评论 2 34
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,077评论 0 23
  • 1 进程介绍 1.1 进程和程序 所谓进程是由正文段(text)、用户数据段(user segment)以及系统数...
    疯狂小王子阅读 1,219评论 0 7
  • Linux 进程管理与程序开发 进程是Linux事务管理的基本单元,所有的进程均拥有自己独立的处理环境和系统资源,...
    JamesPeng阅读 2,442评论 1 14