Linux-进程管理
进程的组成部分
- 已分配内存的地址空间
- 安全属性,包括所有权凭据和特权
- 程序代码的一个或多个执行线程
- 进程状态
进程是如何产生的
- 进程是由父进程复制自己的地址空间创建子进程所产生的。
进程产生的意义
- 子进程的产生意义是为了完成一个目标或者任务。
进程的分类
- 前台进程:与终端相关的进程,通过终端启动的进程
- 注意:也可把在前台启动的进程送往后台,以守护模式运行
- 守护进程:daemon,与终端无关的进程(如内核),在系统引导过程中启动的进程
进程状态
Excuting //运行态
Ready //就绪态,也可以称作睡眠态
Uninterruptible sleep //不可中断的睡眠。不可随时唤醒,只有当IO资源加载成功后才能唤醒
Interruptible sleep //可中断的睡眠。可随时唤醒
Zombie //僵尸进程。正常运行结束了,但是不释放占据的内存
Stopped //停止态,暂停于内存中,但不会被调度,除非手动启动之
进程优先级
- 进程优先级范围:0-139,数字越小,优先级越高
- 0-99:实时优先级,内核调整
- 100-139:静态优先级,用户可控制
- 进程优先级高的特点:
- 获得更多的CPU运行时间
- 更优先获得CPU运行的机会
要修改进程的优先级可以通过调整进程的nice值来实现,nice值越小,优先级越高:
nice值的范围是(-20,19),-20对应100,19对应139
进程优先级调整
renice //进程优先级调整:调整nice值
[root@localhost ~]# ps -elf | grep vi
4 S root 1035 1 0 80 0 - 18181 x64_sy 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
4 S root 5362 5343 0 80 0 - 9096 core_s 15:48 pts/1 00:00:00 vi abc
0 S root 5364 5314 0 80 0 - 3027 - 15:48 pts/0 00:00:00 grep --color=auto vi
[root@localhost ~]# renice -20 5362 //把进程5362优先级调成-20
5362 (process ID) old priority 0, new priority -20
[root@localhost ~]# ps -elf | grep vi
4 S root 1035 1 0 80 0 - 18181 x64_sy 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
4 S root 5362 5343 0 60 -20 - 9096 core_s 15:48 pts/1 00:00:00 vi abc
0 S root 5367 5314 0 80 0 - 3027 - 15:48 pts/0 00:00:00 grep --color=auto vi
进程管理命令
ps //(process state)命令用于列出当前的进程
//常用选项:
a //显示所有与终端有关的进程
u //显示进程是由哪个用户启动的
x //显示所有与终端无关的进程
-e //显示所有进程,与-A效果相同
-l //以长格式显示
-F //显示更详细的完整格式的进程信息
-f //显示更详细的完整格式的进程信息
-H //以进程层级格式显示进程相关信息
-o //根据自己的需要选择要显示的字段
[root@localhost ~]# ps
PID TTY TIME CMD
5314 pts/0 00:00:00 bash
5371 pts/0 00:00:00 ps
[root@localhost ~]# ps -o pid,comm,ni //表示只显示进程号,命令,nice值三个字段
PID COMMAND NI
5314 bash 0
5369 ps 0
[root@localhost ~]# ps aux | head -3
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 179032 13444 ? Ss 15:27 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 18
root 2 0.0 0.0 0 0 ? S 15:27 0:00 [kthreadd]
//aux结果解析:
VSZ //Virtual memory SiZe,虚拟内存集
RSS //ReSident Size,常驻内存集
STAT //进程状态
TIME //运行时的累积时长
[root@localhost ~]# ps -elf | head -3
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 44758 do_epo 15:27 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 18
1 S root 2 0 0 80 0 - 0 - 15:27 ? 00:00:00 [kthreadd]
//ps命令结果解析:
NI //nice值
PRI //优先级
PSR //进程运行在哪个CPU核心上
RTPTRIO //实时优先级
C //运行的CPU编号
STIME //进程的启动时间
VSZ //Virtual memory SiZe,虚拟内存集
RSS //ReSident Size,常驻内存集
STAT //进程状态
TIME //运行时的累积时长
pstree //用于显示当前系统上的进程树(需要安装psmisc)
[root@localhost ~]# mount /dev/cdrom /mnt/
mount: /mnt: WARNING: device write-protected, mounted read-only.
[root@localhost ~]# rpm -ivh /mnt/BaseOS/Packages/psmisc-23.1-4.el8.x86_64.rpm
warning: /mnt/BaseOS/Packages/psmisc-23.1-4.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:psmisc-23.1-4.el8 ################################# [100%]
[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─VGAuthService
├─agetty
├─anacron
├─auditd───{auditd}
├─crond
├─dbus-daemon───{dbus-daemon}
├─firewalld───{firewalld}
├─irqbalance───{irqbalance}
├─polkitd───7*[{polkitd}]
├─rhsmcertd
├─rngd───{rngd}
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───sshd───bash───pstree
│ └─sshd───sshd───bash───vi
├─sssd─┬─sssd_be
│ └─sssd_nss
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───3*[{tuned}]
└─vmtoolsd───2*[{vmtoolsd}]
pgrep //以grep风格指定只显示哪些进程,在当前系统中找符合某些特性的进程,只显示进程号
[root@localhost ~]# ps -ef | grep vi
root 1035 1 0 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
root 5362 5343 0 15:48 pts/1 00:00:00 vi abc
root 13705 5314 0 16:05 pts/0 00:00:00 grep --color=auto vi
[root@localhost ~]# pgrep vi
1035
5362
pidof //根据进程名查找其PID号
[root@localhost ~]# ps -ef | grep vi
root 1035 1 0 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
root 5362 5343 0 15:48 pts/1 00:00:00 vi abc
root 13705 5314 0 16:05 pts/0 00:00:00 grep --color=auto vi
[root@localhost ~]# pidof vi
5362
vmstat //虚拟内存状态查看命令
[root@localhost ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 3177516 3480 359048 0 0 33 9 38 57 0 0 99 0 0
vmstat 1 //表示每1秒刷新一次(一直刷不会停止)
[root@localhost ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 3177408 3480 359088 0 0 32 8 38 56 0 0 99 0 0
0 0 0 3177352 3480 359088 0 0 0 0 89 129 0 0 100 0 0
0 0 0 3177352 3480 359088 0 0 0 0 82 130 0 0 100 0 0
^C
vmstat 1 2 //表示每1秒刷新一次,刷新2次后退出
[root@localhost ~]# vmstat 1 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 3177324 3480 359088 0 0 32 8 38 56 0 0 99 0 0
0 0 0 3177152 3480 359088 0 0 0 0 94 135 0 0 100 0 0
[root@localhost ~]#
free //查看内存信息
[root@localhost ~]# free -m //按MB大小查看
total used free shared buff/cache available
Mem: 3752 294 3102 8 354 3210
Swap: 4043 0 4043
[root@localhost ~]# free -g //按GB大小查看
total used free shared buff/cache available
Mem: 3 0 3 0 0 3
Swap: 3 0 3
//vmstat命令结果解析:
类别 | 项目 | 含义 | 说明 |
---|---|---|---|
Procs | r | 等待执行的任务数 | 展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了 |
b | 处在非中断睡眠状态的进程数 | ||
Memory | swpd | 正在使用的swap大小单位K | |
free | 空闲的内存空间 | ||
buff | 已使用的buff大小,对块设备的读写进行缓冲 | ||
cache | 已使用的cache大小,文件系统的缓存cache | ||
inact | 非活跃内存大小 | ||
active | 活跃的内存大小 | ||
Swap | si | 交换内存使用,由磁盘调入内存 | |
so | 交换内存使用,由内存调入磁盘 | si,so值大,说明真实的内存不够用了,需要加内存了 | |
IO | bi | 从块设备读入的数据总量(读磁盘) (KB/s) | bi的值大,说明正在读东西到内存里去 |
bo | 写入到块设备的数据总理(写磁盘) (KB/s) | bo的值大,说明有很多东西正在写到内存里去 | |
System | in | 每秒产生的中断次数 | |
cs | 每秒产生的上下文切换次数 | in,cs的值大,说明切换的频率很快,跑了很多个进程,CPU不够用了,需要更换更好的CPU了 | |
CPU | us | 用户进程消耗的CPU时间百分比 | us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超过50% 的使用,那么我们就该考虑优化程序算法或者进行加速了 |
sy | 内核进程消耗的CPU时间百分比 | sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性的表现,我们应该检查原因 | |
id | 空闲 | id的值大,说明内存非常空闲 | |
wa | IO等待消耗的CPU时间百分比 | wa的值高时,说明CPU非常忙 |
控制作业
作业分类
Linux作业分为前台作业与后台作业两种。其各自的特点如下:
- 前台作业:通过终端启动,且启动后一直占据了命令提示符
- 后台作业:可以通过终端启动,但启动之后,释放命令提示符,后续的操作在后台完成
- 此类作业虽然被送往后台运行,但其依然与终端相关。如果希望送往后台后,剥离与终端的关系需要执行(nohup COMMAND &)
在后台运行作业
//在命令后跟上&符号可以生成一个后台作业
[root@localhost ~]# sleep 600 &
[1] 13731
//jobs命令用于显示当前所有的后台作业
[root@localhost ~]# jobs
[1]+ Running sleep 600 &
//fg命令用于将后台作业调至前台运行
[root@localhost ~]# fg
sleep 600
//当只有一个后台作业时,直接使用fg命令,不跟任何参数即可将后台作业调至前台运行,但是当有多个作业时则必须跟上%+作业号,也就是上面命令执行结果中以[]括起来的数字。
[root@localhost ~]# jobs
[1]- Running sleep 600 &
[2]+ Running sleep 500 &
[root@localhost ~]# fg %1
sleep 600
//使用ctrl+z可将前台进程发送到后台,此时作业将处于停止状态
[root@localhost ~]# fg %1
sleep 600
^Z
[1]+ Stopped sleep 600
//使用bg命令+作业号可使后台已停止的作业重新运行
[root@localhost ~]# bg %1
[1]+ sleep 600 &
[root@localhost ~]# jobs
[1]- Running sleep 600 &
[2]+ Running sleep 500 &
//kill加上作业号可以手动杀死指定作业
[root@localhost ~]# jobs
[1]- Running sleep 600 &
[2]+ Running sleep 500 &
[root@localhost ~]# kill %1
[1]- Terminated sleep 600
[root@localhost ~]# jobs
[2]+ Running sleep 500 &
//jobs命令的结果中
+ //命令将默认操作的作业
- //命令将第二个默认操作的作业
小拓展:如何不用killall杀死指定进程?
[root@localhost ~]# ps -ef | grep sleep
root 13772 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13773 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13774 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13775 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13776 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13777 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13778 5314 0 16:42 pts/0 00:00:00 sleep 600
root 13784 5314 0 16:42 pts/0 00:00:00 grep --color=auto sleep
[root@localhost ~]# kill -9 $(pidof sleep)
[1] Killed sleep 600
[2] Killed sleep 600
[3] Killed sleep 600
[4] Killed sleep 600
[5] Killed sleep 600
[6]- Killed sleep 600
[7]+ Killed sleep 600
[root@localhost ~]# ps -ef | grep sleep
root 13792 5314 0 16:43 pts/0 00:00:00 grep --color=auto sleep
使用信号控制进程
基本进程管理信号
信号编号 ID | 短名称 | 定义 | 用途 |
---|---|---|---|
1 | HUP | 挂起 | 让一个进程不用重启就可以重读配置文件,并让新的配置信息生效 |
2 | INT | 键盘中断 | 中断一个前台进程。ctrl+c就是用的SIGINT信号 |
9 | KILL | 中断,无法拦截 | 导致立即终止程序。无法被拦截、忽略或处理 |
15 默认值 | TERM | 终止 | 导致程序终止。和SIGKILL不同,可以被拦截、忽略或处理。要求程序终止的友好方式,允许自我清理 |
kill
//kill命令根据ID向进程发送信号。虽其名称为kill,但该命令可用于发送任何信号,而不仅仅是终止程序的信号
//kill后面可以跟完整名称也可以跟简写或数字编号
[root@localhost ~]# 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
killall
//killall后面跟进程名,表示将匹配到的以进程名为名的进程全部杀死
[root@localhost ~]# ps -ef | grep vi
root 1035 1 0 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
root 5362 5343 0 15:48 pts/1 00:00:00 vi abc
root 13757 5314 0 16:37 pts/0 00:00:00 grep --color=auto vi
[root@localhost ~]# killall vi
[root@localhost ~]# ps -ef | grep vi
root 1035 1 0 15:27 ? 00:00:00 /usr/bin/VGAuthService -s
root 13760 5314 0 16:37 pts/0 00:00:00 grep --color=auto vi
监控进程活动
IO负载
负载平均值代表一段时间内感知的系统负载。Linux通过预期服务等待时间的表示来实施平均负载计算
grep 'model name' /proc/cpuinfo
//查看cpu核心数
[root@localhost ~]# grep 'model name' /proc/cpuinfo
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
nproc //取CPU核心数
//nproc相当于grep -c processor /proc/cpuinfo
[root@localhost ~]# grep -c processor /proc/cpuinfo
4
[root@localhost ~]# nproc
4
小拓展:如何不用以上两种方法取CPU核心数?
[root@localhost ~]# grep processor /proc/cpuinfo | wc -l
4
显示负载平均值
uptime
[root@localhost ~]# uptime
16:48:54 up 1:21, 2 users, load average: 0.00, 0.00, 0.00
//此处的load average就表示负载平均值,这三个值代表最近1、5和15分钟的负载情况
//注:用平均值去除以CPU核心数得出来得数值,如果小于1就是正常,如果大于1就说明负载非常大
实时进程监控
top //用于实现全屏动态显示系统信息
//常用选项:
-d //设置延迟时长,top -d 1表示每隔1秒刷新一次,默认每隔5秒刷新
-b //批模式翻屏显示,默认只实时显示一屏,若要显示后面的进程信息则可使用-b选项,与-n #合用,可指定显示翻#屏
[root@localhost ~]# top
top - 14:38:55 up 12 min, 1 user, load average: 0.00, 0.03, 0.04
Tasks: 195 total, 2 running, 193 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st
MiB Mem : 791.5 total, 335.8 free, 225.7 used, 230.1 buff/cache
MiB Swap: 4044.0 total, 4044.0 free, 0.0 used. 435.9 avail Mem
Change delay from 10.0 to
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1048 root 20 0 425276 31020 16200 S 0.1 3.8 0:00.34 tuned
1201 root 20 0 206272 5292 3388 S 0.1 0.7 0:00.09 rsyslogd
1 root 20 0 179076 13360 8576 S 0.0 1.6 0:01.77 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 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
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-kblockd
8 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
9 root 20 0 0 0 0 S 0.0 0.0 0:00.05 ksoftirqd/0
10 root 20 0 0 0 0 R 0.0 0.0 0:00.10 rcu_sched
//在top中交互式子命令:
M //根据驻留内存大小进行排序,默认根据CPU百分比排序
P //根据CPU使用百分比进行排序
T //根据累计时间(占据CPU时长)进行排序
l //是否显示平均负载和启动时间
t //是否显示进程和CPU状态相关信息
m //是否显示内存相关信息
c //是否显示完整的命令行信息
q //退出top命令
k //终止某个进程
1 //显示所有CPU的信息
s //修改刷新时间间隔
//top命令结果解析:
列名(上方) | 含义 |
---|---|
load average | CPU队列中等待运行的任务的个数 |
%Cpu(s) | 多颗CPU平均负载,按1键显示每颗CPU平均负载 |
us | 表示用户空间 |
sy | 表示内核空间 |
ni | 表示调整nice值,CPU占用的比率 |
wa | 表示等待IO完成所占据的时间百分比 |
hi | 表示hard interrupt,硬件中断占据的时间百分比 |
si | 表示软中断占据的时间百分比 |
st | 表示steal,被虚拟化技术偷走的时间(比如运行虚拟机) |
列名(下方) | 含义 |
---|---|
PID | 进程id |
USER | 进程所有者的用户名 |
PR | 优先级 |
NI | nice值。负值表示高优先级,正值表示低优先级 |
VIRT | 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
RES | 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
SHR | 共享内存大小,单位kb |
S | 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程) |
%CPU | 上次更新到现在的CPU时间占用百分比 |
%MEM | 进程使用的物理内存百分比 |
TIME+ | 进程使用的CPU时间总计,单位1/100秒 |
COMMAND | 命令名/命令行 |