Linux 进程管理
概述
本文介绍与进程、服务相关的若干知识。
进程
如果学习过操作系统课程,我们知道:程序是一组代码集合,它存储于硬盘之中,而进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
在 Linux 系统中,进程可简单表示为:PID (进程编号) + PPID (父进程编号) + 基于使用者所得到的权限 + 程序码。
我们最常使用的 bash 就是一个进程,其上输入各种指令便会引发一个 bash 子进程以执行此指令。这里就简单说明单一 bash 环境下的工作管理 (job control):
- 通过在指令尾部添加
&
,该指令便会于 bash 背景中执行,执行完成后,其结果会显示于 bash 页面之上。 - 向正在运行的指令程序输入
ctrl + z
,该指令程序便会暂停执行,并位于 bash 背景之中。 - 借助于指令
jobs
,可查看 bash 背景中各工作的状态信息。 - 借助于指令
fg
,可将某指令程序拉至 bash 页面中执行。 - 借助于指令
bg
,可将背景中某指令程序状态由暂停变更为运行中。 - 借助于指令
kill
,可向背景中某指令程序发送特定signal
,以重启、删除此指令程序。
需要注意的是,如果 bash 关闭,则 bash 背景中各种指令程序随即停止。若不想此场景发生,可使用指令 nohup xxx &
,如此该指令的执行便会位于系统背景之中,此时只有当 Linux 系统关闭,该指令程序才会停止。
接下来,我们简单谈谈 Linux 系统下的进程管理 (process control):
ps
该指令可查看个时间点各进程的运行情况。
通常只需知道两个选项即可:
ps -l
用于查看 bash 之下的各进程运行情况,ps aux
用于查看系统之下的各进程运行情况。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 1689 1688 0 80 0 - 5032 do_wai pts/0 00:00:00 bash
0 R 1000 2101 1689 0 80 0 - 5228 - pts/0 00:00:00 ps
各字段含义如下:
- F 表明此进程的权限类别,若为 4,则表示其为 root 权限。
- S 表明此进程的运行状态,其取值通常有:R (运行中)、S (睡眠中,可被手动唤醒)、D (睡眠中,
不可被手动唤醒,通常处于 I/O 等待)、T (停止中)、Z (僵尸状态,进程已终止,但无法被移除)
- UID/PID/PPID,含义十分明确,忽略。
- 表明此进程的 CPU 使用率。
- PRI/NI 共同指明该进程的运行优先级,PRI 取值越低,进程运行优先级越高。
PRI 动态变化且无法进行调整,由于 PRI 取值与 NI 相关,因此可动态调整它以间接调整 PRI。
借助于 nice 指令,在程序运行之初即指定 NI;借助于 renice,重新调整特定进程的 NI。
- ADDR 指明该进程所依据的程序位于内存哪部分,不知道为什么显示为 '-'。
- SZ 指明该进程目录用掉多少内存。
- WCHAN 仍是指明该进程是否处于运行状态。
- TTY 指明使用者所使用的伪终端设备。
- TIME 指明该进程实际使用 CPU 的时间。
- CMD 指明触发此进程运行的指令。1
2
3
4
5
6
7
8
9
10USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 168896 12052 ? Ss 09:09 0:02 /sbin/init splash
各字段含义如下:
- USER 指明该进程的所属账号。
- PID/%CPU/%MEM,含义十分明确,忽略。
- VSZ 指明该进程用掉的虚拟内存量。
- RSS 指明该进程占用的固定内存量。
- TTY 含义同上。
- STAT 指明该进程的运行状态,含义同 S。
- START/TIME/MOMMAND,含义十分明确,忽略。通常情况下,当子进程运行完成后,父进程应当合理终止它。但是由于系统不稳定或者程序编写问题,会造成某些进程虽已运行完成,但是未被终止,这种进程便被称为
zombie process
(即僵尸进程),其状态便为Z
。top
该指令可动态持续侦测各进程的运行情况。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28top - 10:59:28 up 1:49, 2 users, load average: 0.27, 0.30, 0.24
Tasks: 247 total, 1 running, 245 sleeping, 1 stopped, 0 zombie
%Cpu(s): 0.0 us, 1.5 sy, 0.0 ni, 98.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 7929.7 total, 6317.6 free, 409.2 used, 1202.9 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 7222.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
860 root 20 0 1120560 46824 26060 S 0.6 0.6 0:54.76 containerd
top 指令输出结果比较多,我们一行一行介绍:
第一行:
10:59:28 指明当前时间;up 1:49 指明自开机至此的系统运行时间;2 users 指明系统使用者个数;
load average: xxx 指明 1/5/15 分钟内的平均负载情况 (即系统平均需要运行几个进程)。
第二行:
各字段含义比较清晰,指明系统共计多少进程,多少处于运行状态,多少处于运行状态,...。
第三行:
该行从各个方面总体评估 CPU 的使用情况,即哪些方面占用了多少 CPU。
us(user) 表示用户空间的 CPU 使用情况;sy(system) 表示系统空间的 CPU 使用情况;
ni(niceness) 表示修改过优先级的进程的 CPU 使用情况;id(idle) 表示空闲 CPU 的使用情况;
wa(wait) 表示 I/O 等待的 CPU 使用情况;hi(hard interrupt) 表示硬中断的 CPU 使用情况;
si(soft interrupt) 表示软中断的 CPU 使用情况;
st(stole time) 表示分配给当前虚拟机的 CPU 时间中,被本机其他虚拟机所偷用的 CPU 使用情况。
第四行:
各字段含义比较清晰,指明系统的内存总量、空闲内存量、已用内存量和用作 buff 的内存量。
第五行:
与第四行各字段类似,只不过指的是内存交换空间的相关指标。
第六行:
PR 与上方的 PRI 同义;VIRT 指明该进程所用的内存总量,包括 Mem + Swap;
RES 指明该进程真实使用的 Mem 之中的内存量;SHR 指明该进程所用的共享内存量;默认情况下,指令
top
以 PID 排序侦测结果。若需按照内存使用率或 CPU 使用率进行排序,可在侦测页面中输入M
或C
。pstree
该指令能够将各进程按照父子关系组织成为一棵树。
1
2
3
4
5systemd─┬─ModemManager───2*[{ModemManager}]
├─ ***
├─sshd───sshd───sshd───bash─┬─pstree
│ └─vim
├─ ***从中可以看到进程
systemd
为所有进程的唯一父进程。kill/killall
该指令可向特定进程发送特定
signal
,以启动、终止、重启该特定进程。常见
signal
:SIGHUP
(启动被终止的进程)、SIGKILL
(强制终止进程)、SIGSTOP
(暂停进程)。
最后简单介绍若干查看系统资源的指令:
free
–> 查看系统内存使用情况。uname
–> 查看系统与核心相关参数信息。uptime
–> 查看系统启动时间与工作负载情况。netstat
–> 查看网络与 port 使用的相关信息。dmesg
–> 查看核心所产生的讯息。vmstat
–> 动态侦测系统资源的使用情况。
服务
服务,通常也称为 “daemons”,即一直处于运行状态的进程,它能向外界提供一种功能。
在此,我们介绍两种服务,一种与例行性工作调度相关,一种与日志记录相关。
在 Linux 系统中,存在两种例行性工作调度:突发型 (即某个特定时间点执行,它借助于 atd
服务而存在,使用指令 at
可定义此类任务)、循环型 (即定期执行,它借助于 crond
服务而存在,使用指令 crontab
可定义此类任务)。
对于
at
和cron
而言,分别存在xx.allow
和xx.deny
以限制所定义的任务是否可被执行,另外使用者所创建的任务分别被放置于/var/spool/at
和/var/spool/cron
之中。
值得说一下的是:crond
服务通常也为系统所使用,在 /etc/crontab
配置文件中,其中定义了若干周期性执行 /etc/cron.d/*
中脚本 (其脚本功能可能是更新 locate 数据库,也可能是轮替日志文件) 的任务。
另外,考虑一种场景:假定某任务每周日晚上执行,但是某周六系统停电,电脑关机,自然该任务这周日不会执行。周一启动系统后,时间已经过期,crond
自然会等到本周日晚上才执行此任务,然而如果该任务比较重要的话,最好还是周一就执行一次。为解决这个问题,anacron
进程被启用,它会自动判断哪些任务逾期未执行,然后自动执行它们。
十分有意思的是:
anacron
由crond
控制而周期执行,anacron
又会反过来判断各任务是否逾期未完成。
在 Linux 系统中,日志记录主要分为两部分:一部分由 systemd-journald
提供,系统启动之初的各种日志信息均会由此记录;一部分由 rsyslog
提供,它会记录系统运行期间各进程的日志信息,普通程序也可基于相关规范将日志信息发与 rsyslog
以供其管理。
各种日志文件通常均位于
/var/log
之中。随着系统的运行,日志文件将会越来越大,那么就存在
logrotate
这一服务,它会基于/etc/logrotate.conf
及/etc/logrotate.d/*
中配置文件内容,按照特定方式轮替日志文件 (以某种格式备份当前所用日志文件,随后清空当前所用日志文件。另外,过早的日志文件可能会被自动清除)。