一个称职的系统管理员,必须要熟悉进程的管理流程才行。
进程的介绍
什么是进程?
在Linux系统当中,触发任何一个事件时,系统都会将它定义为一个进程,并且给予这个进程一个id,称为pid,同时依据触发这个进程的用户与相关属性关系,给予这个pid一组有效的权限设置。从此以后,这个pid能够在系统上面进行的操作,就与这个pid的权限有关了。
如何产生一个进程?
其实很简单,就是“执行一个程序或命令”就可以触发一个事件而取得一个pid,因为系统仅认识二进制文件,所以当我们让系统工作时,就需要启动一个二进制文件,这个二进制文件也就是一个程序。
程序一般是放置在磁盘当中,然后通过用户的执行触发,触发后会加载到内存中成为一个个体,也就是进程。为了让操作系统可以管理这个进程,因此进程有给予执行者的权限/属性等参数,并包括进程所需要的脚本和数据或文件数据等,最后在给予一个pid。系统就是通过这个pid来判断该process(进程)是否具有权限进行工作的。
程序和进程的区别是什么?
程序(program):通常为二进制程序放置在存储媒介中(如硬盘、光盘、软盘、磁带等),以物理文件的形式存在。
进程(process):程序被触发后,执行者的权限和属性、程序的程序代码与所需数据等都会被加载到内存中,操作系统并给予这个内存内的单元一个标识符(pid),可以说,进程就是一个正在运行中的程序。
子进程与父进程
举例说明,当我们登录系统后,会取得一个bash的shell并得到一个pid,然后我们用这个bash提供的接口去执行另一个命令,比如新建一个文件touch test.txt,执行的另一个命令也会被触发成为pid,那么后来执行的另一个命令所产生的pid就是子进程,而我们原本的bash环境下的pid就是父进程。
如何判断某个进程的父进程是哪个?
这是通过Parent PID(PPID)判断的,由以下命令可以看出,ps命令的父进程(ppid)是bash的进程(pid)。
1 | [root@localhost test6]# ps -l |
进程的查看
进程的查看
如何查阅系统上正在运行的进程?
使用静态的ps或者动态的top,还可以使用pstree查看程序树之间的关系。
ps:将某个时间点的进程运行情况选取下来
先来说一下ps命令,常用方式有这么几种:
查看系统所有的进程数据 ps aux
也能够查看所有系统的数据 ps -lA
连同部分进程树状态 ps axjf
参数:
-A:所有的进程都显示出来,与-e具有同样的作用。
-a:不与terminal有关的所有进程。
-u:有效用户(effective user)相关的进程。
x:通常与a参数一起使用,可以列出较完整信息。
输出格式规划:
l:较长、较详细的将pid的信息列出。
j:工作的格式(jobs format)
-f:做一个更为完整的输出。
注意:一般只需要背下来两个使用方式即可,一个是只能查阅自己bash程序的“ps -l”,另一个是可以查看所有系统正在运行的程序的“ps aux”。所以我们这里也仅通过示例来讲解一下这两个使用方式。
下面通过几个示例将显示的数据详细介绍一下:
示例1:
将目前属于你自己这次登录的pid与相关信息列出来(只和自己的bash有关)
1 | [root@localhost test6]# ps -l |
显示数据所表示的含义:
F:代表这个进程的标志(process flags),说明这个进程的权限,常见号码有:
4:表示进程的权限为root
1:表示此子进程仅可以进行复制(fork)而无法实际执行(exec)
S:代表这个进程的状态(STAT),主要状态有:
R(Running):该进程正在运行中
S(Sleep):该进程目前正在睡眠状态(idle),但可以被唤醒(signal)
D:不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况(ex>打印)
T:停止状态(stop),可能在工作控制(后台暂停)或除错(traced)状态
Z(Zombie):“僵尸”状态,进程已经终止但无法被删除到内存外
UID:代表此进程被该UID所拥有
PID:进程的PID号码
PPID:此进程的父进程PID号码
C:代表CPU使用率,单位是百分比
PRI:Priority的缩写
NI:Nice的缩写
ADDR:kernel function,指出该进程在内存的哪个部分,如果是个running的进程,一般就会显示”-“
SZ:代表此进程用掉多少内存
WCHAN:表示目前进程是否运行中,若为”-“,表示正在运行中
TTY:登录者的终端机位置,若为远程登录则使用动态终端接口(pts/n)
TIME:使用掉的CPU时间,注意,是此进程实际花费CPU运行的时间,不是系统时间
CMD:是command的缩写,造成此程序的触发进程命令是什么
示例2:
列出目前所有正在内存当中的进程。
1 | [root@localhost test6]# ps aux |
说一下各个字段的意义:
USER:该进程属于哪个用户帐号的
PID:该进程的进程标识符
%CPU:该进程使用掉的CPU资源百分比
%MEM:该进程所占用物理内存百分比
VSZ:该进程使用掉的虚拟内存量(KB)
RSS:该进程占用的固定内存量(KB)
TTY:该进程是在哪个终端机上面运行,如果与终端机无关,则显示”?“。另外,tty1-tty6是本机上面的登录者程序,如果为pts/0等,则表示由网络连接进主机的进程。
STAT:该进程目前的状态,状态显示与ps -l的S标识相同(R/S/T/Z)
START:该进程被触发启动的时间
TIME:该进程实际使用CPU运行的时间
COMMAND:该进程的实际命令
top:动态查看进程的变化
相对于ps是选取一个时间点的进程状态,top则可以持续检测进程运行的状态,使用方式如下:
top [-d 数字] | top [-bnp]
参数:
-d:后面可以接秒数,就是整个进程界面更新的秒数,默认是5秒
-b:以批次的方式执行top,还有更多的参数可以使用。通常会搭配数据流重定向来将批处理的结果输出成为文件。
-n:与-b搭配,意义是,需要进行几次top的输出结果。
-p:指定某些个pid来进行查看监测
在top执行过程当中,可以使用的按键命令:
?:显示在top当中可以输入的按键命令
P:以CPU的使用资源排序显示
M:以内存的使用资源排序显示
N:以PID来排序显示
T:由该进程使用的CPU时间累积(TIME+)排序
k:给予某个pid一个信号(signal)
r:给予某个pid重新制定一个nice值
q:离开top软件的按键
1 | top - 14:26:44 up 15:17, 2 users, load average: 0.00, 0.01, 0.05 |
top分为两个界面,上面的界面为整个系统的资源使用状态,基本上总共有六行,显示的内容依序是:
第一行(top…):这一行显示的信息分别为:目前的时间,即是14:26:44
那个选项;开机到目前为止所经过的时间,即使up 15:17
那个选项;已经登录系统的用户人数,即是2 users
那个选项;系统在1,5,15分钟的平均工作负载,即是load average: 0.00, 0.01, 0.05
那个选项,代表的是1,5,15分钟,系统平均要负责运行几个进程(工作)的意思,越小代表系统越闲置,如果高于1,就要注意你的系统压力是否太高了。
第二行(Tasks…):显示的是目前进程的总量与个别进程在什么状态(running,sleeping,stopped,zombie)。比较需要注意的是最后的zombie那个数值,如果不是0,就要好好看到底是哪个进程变成僵尸进程了。
第三行(%Cpu…):显示的是CPU的整体负载,每个选项可使用”?“查阅。需要特别注意的是wa,那个选项代表的是I/O wait,通常你的系统会变慢都是I/O产生的问题比较大,因此这里要注意这个选项耗用CPU的资源,另外,如果是多内核设备,可以按下数字键”1“来切换成不同CPU的负载率。
第四行与第五行:表示目前的物理内存与虚拟内存(Mem/Swap)的使用情况。特别强调一下,要注意的是Swap的使用量要尽量少,如果Swap被大量使用,表示系统物理内存不足。
第六行:这个是当在top进程当中输入命令时显示状态的地方。
top下半部分的界面,则是每个进程使用资源的情况。比较需要注意的是:
PID:每个进程的id
USER:该进程所属的用户
PR:Priority的简写,进程的优先执行顺序,越小越早被执行
NI:Nice的缩写,与Priority有关,也是越小越早被执行
%CPU:CPU的使用率
%MEM:内存的使用率
TIME+:CPU使用时间的累加
top默认使用CPU使用率(%CPU)作为排序的重点,如果你想要使用内存使用率排序,则可按下”M“按键,若要恢复则按下”P“按键,如果想离开top,则按下”q“按键。
如果你想将top的结果输出成为文件,可以看下面这个示例。
示例3:
将top的信息进行2次,然后将结果输出到/tmp/top.txt
top -b -n 2 > /tmp/top.txt
仅查看单一进程,请看下面示例。
示例4:
我们自己的bash PID 可由 $$ 变量取得,请使用top持续查看该PID
1 | [root@localhost test6]# echo $$ |
这样就只会显示你指定的pid
示例5:
承接上例,上面的NI值为0,想要修改为10
在top界面中,按下”r“按键,显示”PID to renice [default pid = 12202]”如下:
1 | top - 15:03:35 up 15:53, 2 users, load average: 0.00, 0.01, 0.05 |
输入进程号pid,显示”Renice PID 12202 to value“如下:
1 | top - 15:03:35 up 15:53, 2 users, load average: 0.00, 0.01, 0.05 |
输入新Nice值10,显示如下:
1 | top - 15:07:47 up 15:58, 2 users, load average: 0.00, 0.01, 0.05 |
一般如果想找出最损耗CPU资源的进程,就是使用top,然后强制使用CPU使用资源来排序(在top当中按下”P“按键),就可以很快知道结果。
pstree
格式:
pstree [-A|U] [-up]
参数:
-A:各进程树之间的连接以ASCII字符来连接
-U:各进程树之间的连接以utf8码的字符连接,在某些终端接口下可能会有错误
-p:同时列出每个进程的pid
-u:同时列出每个进程的所属帐户名称
进程的管理
进程之间是可以互相控制的,比如我们可以关闭、重启服务器软件,服务器软件本身是个程序,我们既然可以关闭或启动程序,当然就可以控制程序,每个运行的程序都有一个进程号(pid),如果我们想控制程序,我们只需要给该进程号发送一个信号(signal)告诉该程序,我们想让它干什么。所以这个信号很重要,到底有多少信号呢?我们可以通过命令kill -l
查看。
1 | [root@localhost ~]# kill -l |
这么多信号,常见的几个如下表格:
代号 | 名称 | 内容 |
---|---|---|
1 | SIGHUP | 启动被终止的进程,可以让该pid重新读取自己的配置文件,类似重新启动 |
2 | SIGINT | 相当于键盘输入[ctrl] + c 来中断一个进程的进行 |
9 | SIGKILL | 代表强制中断一个进程的进行,如果该进程进行到一半,那么尚未完成的部分可能会有”半产品“产生,类似vim会有.filename.swp保留下来 |
15 | SIGTERM | 以正常的结束进程来终止该进程。由于是正常的终止,所以后续的操作会将它完成。不过,如果该进程已经发生问题,就是无法使用正常的方法终止时,输入这个SIGTERM也是无用的 |
17 | SIGCHLD | 相当于用键盘输入[ctrl] + z 来暂停一个进程的进行 |
我们常用的只有1,9,15,一般记住这三个的意义即可。
如何传送一个信号给某个进程呢?用kill或killall,下面分别介绍一下:
kill -signal PID
kill可以帮我们把这个signal传送给某个工作(%jobnumber)或者某个PID(直接输入数字)。需要强调的是,kill后面直接加数字和加上%number的情况是不同的!因为工作控制中有1号工作,但是PID的1号则是专指”init“这个进程。关闭”init“这个进程,你的系统就死掉了。所以一定要记得%是专门用在工作控制上的。
killall -signal 命令名称
因为kill后面必须加上pid或者%jobnumber,所以kill要配合ps,pstree等命令先找到对应的进程id,而且如果我们有多个PHP进程在运行,想要终止所有PHP进程,就需要一个一个的killPHP进程的进程号,比较麻烦。我们可以使用killall直接给进程名称发送signal。
格式:
killall [-iIe] [command name]
参数:
-i:interactive的意思,交互式的,若需要删除时,会出现提示符给用户。
-e:exact的意思,表示后面接的command name 要一致,但整个完整的命令不能超过15个字符
-I:命令名称(可能含参数)忽略大小写。
注意:如果我们想要终止某个程序的所有进程,最好使用参数-i,防止误终止不能终止的进程。
进程执行顺序
哪个进程被执行的优先序比较高,就得考虑到程序的优先执行序(Priority)与CPI调取。
Priority与Nice值
Linux给予进程一个所谓的”优先执行序“(priority,PRI),这个PRI值越低代表进程越优先的意思,不过这个PRI值是由内核动态调整的,用户无法直接调整PRI的值。
还记得我们在哪看到过PRI吗?
1 | [root@localhost test6]# ps -l |
因为PRI是内核调整的,我们用户无权干涉PRI。那么如果你想要调整进程的优先执行序时,就要通过Nice值了,Nice值就是上面的NI。一般来说,PRI与NI的相关性如下:
PRI(new) = PRI (old) + nice
不过你还要特别注意,如果原本的PRI是50,并不是我们给予一个nice=5,就会让PRI变成55。因为PRI是系统”动态“决定的,所以,虽然nice值是可以影响PRI,不过,最终的PRI仍是要经过系统分析后才会决定的。另外,有几点需要注意一下:
- nice的值是有正负的,而既然PRI越小越早被执行,所以,当nice值为负值时,那么该程序就会降低PRI值,即会变得优先被处理的。
- nice的值可调整的范围是-20~19
- root可以随意调整自己或他人进程的Nice值,且范围是-20~19
- 一般用户只可以调整自己进程的Nice值,且范围是0~19(避免一般用户抢占系统资源)
- 一般用户仅可将nice值越调越高,例如本来nice为5,则将来仅能调整到大于5
也就是说,要调整某个进程的优先执行序,就是调整该进程的nice值。调整某个进程的nice值有两种方式:
- 一开始执行程序就立即给予一个特定的nice值,用nice命令
- 调整某个已存在的PID的nice值,用renice命令
nice:新执行的命令即给予新的nice值
格式:
nice [-n 数字] command
参数:
-n:后面接一个数字,数值的范围是-20~19
command:命令名称
renice:已存在进程的nice重新调整
格式:
renice [number] PID
参数:
PID:某个进程的pid