Linux 温习(二): 进程管理
- 陈大剩
- 2023-02-01 20:03:27
- 966
进程简介
进程的含义为正在运行的程序,包括这个运行的程序所占用的系统资源。进程是具有一定独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度的一个独立单位。同一个程序,同一时刻被两次运行了,它们就是两个独立的进程。
进程是已启动的可执行程序的运行实例。进程有以下组成部分。
- 已分配内存的地址空间。
- 安全属性,包括所有权凭据和特权。
- 程序代码的一个或多个执行线程。
- 进程状态。
每个进程都有唯一的进程标识 PID,一个 PID 只能标识一个进程,PPID 为父进程 ID,需要给该进程分配系统资源。
进程状态
进程状态是指程序执行过程中的变化。进程状态随着程序的执行和外界条件的变化而转换。
一般分为3类:
- 就绪态:进程已经具备运行条件,但是 CPU 还没有分配过来。
- 运行态:进程占用 CPU,并在 CPU 上运行。
- 阻塞态:进程因等待某件事发生而暂时不能运行。
查看进程
静态查看进程
ps
命令可以查看静态进程,仅仅是捕捉某一个瞬间某一个进程的状态,类似于给进程制作快照。使用 ps aux
命令查看当前目录的进程。
> ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 125484 3916 ? Ss 09:07 0:01 /usr/lib/systemd/systemd --switched-root --system --de
root 2 0.0 0.0 0 0 ? S 09:07 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 09:07 0:00 [kworker/0:0H]
root 5 0.0 0.0 0 0 ? S 09:07 0:00 [kworker/u256:0]
root 6 0.0 0.0 0 0 ? S 09:07 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 09:07 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 09:07 0:00 [rcu_bh]
每列数据代表意义
列名 | 说明 | 列名 | 说明 | |
---|---|---|---|---|
USER | 运行进程的用户 | RSS | 占用实际内存 | |
PID | 进程ID | TTY | 进程运行的终端 | |
%CPU | CPU占用率 | STAT | 进程状态 | |
%MEM | 内存占用率 | TIME | 进程累计占用 CPU 时间 | |
VSZ | 占用虚拟内存 | COMMAND | 进程发起者 |
其中,VSZ
与 RSS
可以简单理解为房子的建筑面积与使用面积;当 TTY 为 ?
时,表示不依赖任何终端运行。
使用 man
工具查看 STAT
,其中,R 表示运行,S 表示可中断休眠,D 表示不可中断休眠,T 表示停止的进程,Z 表示僵死的进程,X 表示死掉的进程。
我们在查看 CUP 占用率时,一般会希望进程按照 CPU 占用百分比的降序排列,此时可以使用 psaux --sort-%cpu
命令。
> ps -axu --sort -%cpu
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
redis 1311 0.1 0.2 163216 8372 ? Ssl 09:07 0:04 /www/server/redis/src/redis-server 0.0.0.0:6379
root 1 0.0 0.1 125484 3916 ? Ss 09:07 0:01 /usr/lib/systemd/systemd --switched-root --system --de
root 2 0.0 0.0 0 0 ? S 09:07 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 09:07 0:00 [kworker/0:0H]
root 5 0.0 0.0 0 0 ? S 09:07 0:00 [kworker/u256:0]
ps -ef
命令可以查看 UID、PID、PPID 等信息
> ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:07 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0 09:07 ? 00:00:00 [kthreadd]
root 4 2 0 09:07 ? 00:00:00 [kworker/0:0H]
root 5 2 0 09:07 ? 00:00:00 [kworker/u256:0]
root 6 2 0 09:07 ? 00:00:00 [ksoftirqd/0]
root 7 2 0 09:07 ? 00:00:00 [migration/0]
root 8 2 0 09:07 ? 00:00:00 [rcu_bh]
一般情况下,并不是所有显示的内容都有意义,为了快速查找,需要显示的内容简洁并有针对性,我们可以使用 ps axo
命令自定义显示的字段。
> ps -axo pid,ppid,user,%cpu
PID PPID USER %CPU
1 0 root 0.0
2 0 root 0.0
4 2 root 0.0
常用的查看指定进程 PID 的方法
- 使用
cat
命令> cat /run/sshd.pid 1118
- 使用
pidof
命令> pidof sshd 2793 1118
- 使用
pgrep
命令> pgrep sshd 1118 2793
动态查看进程
top
命令可以实时动态地显示进程,类似于 Windows 系统中的任务管理器。使用 top
命令动态查看进程时,进程信息分为上下两部分,上面为整体信息,下面为每一个进程的信息。系统默认更新时间为3秒,也可以按回车键立即更新。
信号控制进程
在进程运行过程中,若由于某些原因需要终止该进程,用户可以给予该进程一个信号( signal ).进程接收到信号之后,就会依照信号的要求做出相应的反应。
> top
top - 10:40:05 up 1:32, 1 user, load average: 0.00, 0.01, 0.05
Tasks: 131 total, 1 running, 129 sleeping, 0 stopped, 1 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 3861256 total, 2768628 free, 665848 used, 426780 buff/cache
KiB Swap: 4063228 total, 4063228 free, 0 used. 2893728 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
656 root 20 0 273184 4816 3688 S 0.3 0.1 0:05.22 vmtoolsd
3078 root 20 0 0 0 0 S 0.3 0.0 0:00.09 kworker/0:0
3125 root 20 0 162104 2280 1596 R 0.3 0.1 0:00.01 top
1 root 20 0 125484 3916 2584 S 0.0 0.1 0:01.42 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
5 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/u256:0
6 root 20 0 0 0 0 S 0.0 0.0 0:00.04 ksoftirqd/0
7 root rt 0 0 0 0 S 0.0 0.0 0:00.05 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:03.17 rcu_sched
10 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 lru-add-drain
上半部分是系统整体统计信息:
top - 16:23:30:当前时间。
up 1: 32:启动后运行时间。
1 users:当前在线用户数。
load average: 0.00, 0.01, 0.05:CPU最近1分钟、5分钟、15分钟平均负载值。
Red Hat 官方手册解释说,假如系统有 4 个 CPU ,把每个时间段的平均负载值除以 4,所得到的数值为每个 CPU 的负载,如果该值大于 1,表明 CPU 过载。
Tasks: 131 total:进程个数。
l running:正在使用CPU的进程个数。
129 sleeping:进程休眠个数。
0 stopped:进程停止个数。
1 zombie:进程僵死个数。
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st:CUP使用情况。
KiB Mem : 3861256 total, 2768628 free, 665848 used, 426780 buff/cache:内存使用情况。
KiB Swap: 4063228 total, 4063228 free, 0 used. 2893728 avail Mem:交换分区使用情况。
特殊排序
- 按 M 键以内存占用率排序。
- 按 Р 键以CPU占用率排序。
- 按 N 键以PID数值大小排序。
- 按 R 键对排序进行反转。按 F 键显示自定义显示字段。按上下键移动。按空格键选中。按 q 键退出自定义显示字段。按 W 键保存自定义显示字段。
- 按 1 键显示所有 CPU 的负载,当前为 2 个 CUP。
- 在 top 命令后添加参数
-d
- 添加
-u
参数可以查看指定用户的进程。
信号控制进程
在进程运行过程中,若由于某些原因需要终止该进程,用户可以给予该进程一个信号( signal ).进程接收到信号之后,就会依照信号的要求做出相应的反应。
kill 命令
Linux 中的 kill
命令用来终止指定进程的运行。首先使用 ps/pidof/top 等工具获取进程 PID,然后使用 kill 命令来杀死该进程。kill 命令通过向进程发送指定的信号来结束相应的进程,在默认情况下,采用编号为15的 TERM 信号。使用 kill -1
命令查看全部信号。
> kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
几种常见的信号
信号编号 | 名称 | 特性及意义 |
---|---|---|
1 | SIGHUP | 启动被终止的进程,重新加载,PID不会发生变化 |
9 | SIGKILL | 强制终止进程,使用此信号可能导致进程无法再次启动 |
15 | SIGTERM | 默认信号,以正常流程终止进程,允许进程释放资源。若进程已经出现问题,无响应,此信号将不起作用 |
18 | SIGCONT | 恢复进程 |
19 | SIGSTOP | 暂停进程 |
使用 pidof
命令查看 nginx 服务进程 PID,然后测试信号 SIGHUP。例如,nginx 配置文件发生改变,希望重新加载。
> pidof nginx
3510 3509 3508 3507 3506
> kill -1 3506
> pidof nginx
3524 3523 3522 3506
测试信号 SIGTERM,该信号为默认信号,可省略输入 15 编号,服务器进程停止。
> pidof sshd
1118
> kill 1118
> pidof sshd
killall 命令
killall 命令可以用于终止某个指定名称的服务所对应的全部进程。
> killall nginx
Linux 终止并不等于停止
进程优先级
进程优先级是一个数值,动态的优先级和静态的优先级决定了进程被CPU处理的顺序。一个拥有更高进程优先级的进程被CPU 处理的概率更高。由于不是每个进程都同样重要,可以让进程调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的调度策略为SCHED_OTHER (也称为SCHED_NORMAL),但还有其他一些调度策略用于不同的目的。SCHED_OTHER 调度策略使用的进程的相对优先级称为进程的 nice 值,有40个不同级别,其范围为-20~19,数值越小优先级越高,数值越大优先级越低。例如,-20的优先级最高,该进程不倾向于让出CPU;19的优先级最低,该进程容易将CPU让给其他进程。
每个CPU(或CPU核心)在一个时间点上只能处理一个进程,通过时间片技术,Linux系统能够运行的进程(和线程数)可以超出实际可用的CPU及其核心数量。Linux 内核进程调度程序将多个进程在 CPU 核心上快速切换,从而造成多个进程在同时运行的假象。普通用户调整应用程序优先权值的范围为0~19,只有超级用户有权使用更高的优先权值。
使用 top 命令动态查看nice级别
使用 top
命令可以查看 nice 级别,其中,NI
列表示实际 nice 级别,PR
列将nice级别映射到更大优先级队列,-20 映射到 0,+19 映射到 39,具体如下所示。
> top
top - 16:23:30 up 25 days, 10:00, 1 user, load average: 4.61, 4.67, 4.71
Tasks: 283 total, 2 running, 281 sleeping, 0 stopped, 0 zombie
%Cpu(s): 13.7 us, 0.5 sy, 0.0 ni, 68.9 id, 16.8 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 32102.6 total, 390.8 free, 4089.2 used, 27622.6 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 27439.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
486930 root 20 0 30.0g 2.7g 112264 S 97.7 8.7 1051:22 python
505869 root 20 0 29.7g 2.7g 87660 D 34.9 8.6 0:41.88 python
505885 root 20 0 29.7g 2.7g 87668 D 31.6 8.6 0:41.41 python
505917 root 20 0 29.7g 2.7g 87648 D 30.9 8.6 0:41.12 python
505901 root 20 0 29.7g 2.7g 87672 R 30.6 8.6 0:41.35 python
426838 root 20 0 0 0 0 I 0.3 0.0 0:03.69 kworker/12:2-mm_percpu_wq
505961 hut 20 0 7636 3692 2840 R 0.3 0.0 0:00.02 top
1 root 20 0 167760 10388 5512 S 0.0 0.0 0:20.86 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.42 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 rcu_par_gp
5 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 netns
7 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-events_highpri
9 root 0 -20 0 0 0 I 0.0 0.0 0:00.93 kworker/0:1H-events_highpri
使用ps命令查看nice级别
使用 ps
命令查看 nice 级别。
> ps axo pid,command,nice,cls --sort=-nice
PID COMMAND NI CLS
117 [khugepaged] 19 TS
116 [ksmd] 5 TS
1 /sbin/init 0 TS
2 [kthreadd] 0 TS
11 [rcu_tasks_rude_] 0 TS
12 [rcu_tasks_trace] 0 TS
13 [ksoftirqd/0] 0 TS
14 [rcu_sched] 0 TS
15 [migration/0] - FF