LINUX 进程管理学习笔记
关于运维来说,进程是不可缺少的一环,也是重点之重了,在服务器卡机或者出现任何状态的时候基本上都是先看一下进程,看看有哪些软件占用的CPU多一些,占用的资源多一些,然后去kill掉一些不必要的进程,总之通过查看进程,大概知道服务器的一个运行状况。
1.1 program & process 介绍:
程序 (program):通常为 binary program ,放置在储存媒体中 (如硬盘、光盘、软盘、磁带等), 为实体文件的型态存在;
进程(process):程序被触发后,运行者的权限与属性、程序的程序码与所需数据等都会被加载内存中, 操作系统并给予这个内存内的单元一个识别码 (PID),可以说,进程就是一个正在运行中的程序。
进程和线程:一个独立程序的运行称为一个进程, 在进程里并发执行的不同部分称为线程. 由这个进程引发的另外的独立程序运行为这个进程的子进程
1.2 program & process 关系:
程序和进程(process)的区别又是什么呢?
进程是程序的一个具体实现。只有食谱没什么用,我们总要按照食谱的指点真正一步步实行,才能做出菜肴。进程是执行程序的过程,类似于按照食谱,真正去做菜的过程。同一个程序可以执行多次,每次都可以在内存中开辟独立的空间来装载,从而产生多个进程。不同的进程还可以拥有各自独立的IO接口。
操作系统的一个重要功能就是为进程提供方便,比如说为进程分配内存空间,管理进程的相关信息等等,就好像是为我们准备好了一个精美的厨房。
2.1 进程查看 ps:
[root@www ~]# ps 选项
选项与参数:
-A :所有的 process 均显示出来,与 -e 具有同样的效用;
-a :不与 terminal 有关的所有 process ;
-u :有效使用者 (effective user) 相关的 process ;
x :通常与 a 这个参数一起使用,可列出较完整资讯。
输出格式规划:
-l :较长、较详细的将该 PID 的的资讯列出;
-j :工作的格式 (jobs format)
-f :做一个更为完整的输出。
2.1 进程查看:
ps -l 结果,如下图:
ps aux 结果,如下图:
2.1 进程查看 ps -l 显示结果解析:
ps -l 则仅列出与你的操作环境 (bash) 有关的程序而已, 参数解释如下:
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/PID/PPID:代表『此程序被该 UID 所拥有/程序的 PID 号码/此程序的父程序 PID 号码』
C:代表 CPU 使用率,单位为百分比;
PRI/NI:Priority/Nice 的缩写,代表此程序被 CPU 所运行的优先顺序,数值越小代表该程序越快被 CPU 运行。
ADDR/SZ/WCHAN:都与内存有关,ADDR 是 kernel function,指出该程序在内存的哪个部分,如果是个 running 的程序,一般就会显示『 - 』 / SZ 代表此程序用掉多少内存 / WCHAN 表示目前程序是否运行中,同样的, 若为 - 表示正在运行中。
TTY:登陆者的终端机位置,若为远程登陆则使用动态终端介面 (pts/n);
TIME:使用掉的 CPU 时间,注意,是此程序实际花费 CPU 运行的时间,而不是系统时间;
CMD:就是 command 的缩写,造成此程序的触发程序之命令为何。
2.2 进程查看 ps aux显示结果解析:
在 ps aux 显示的项目中,各栏位的意义为:
USER:该 process 属於那个使用者帐号的?
PID :该 process 的程序识别码。
%CPU:该 process 使用掉的 CPU 资源百分比;
%MEM:该 process 所占用的实体内存百分比;
VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
RSS :该 process 占用的固定的内存量 (Kbytes)
TTY :该 process 是在那个终端机上面运行,若与终端机无关则显示 ?,另外, tty1-tty6 是本机上面的登陆者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。
STAT:该程序目前的状态,状态显示与 ps -l 的 S 旗标相同 (R/S/T/Z)
START:该 process 被触发启动的时间;
TIME :该 process 实际使用 CPU 运行的时间。
COMMAND:该程序的实际命令为何
2.3 进程实时查看 top 使用参数:
[root@www ~]# top [-d 数字] | top [-bnp]
选项与参数:
-d :后面可以接秒数,就是整个程序画面升级的秒数。默认是 5 秒;
-b :以批量的方式运行 top ,还有更多的参数可以使用喔!
通常会搭配数据流重导向来将批量的结果输出成为文件。
-n :与 -b 搭配,意义是,需要进行几次 top 的输出结果。
-p :指定某些个 PID 来进行观察监测而已。
在 top 运行过程当中可以使用的按键命令:
? :显示在 top 当中可以输入的按键命令;
P :以 CPU 的使用资源排序显示;
M :以 Memory 的使用资源排序显示;
N :以 PID 来排序喔!
T :由该 Process 使用的 CPU 时间累积 (TIME+) 排序。
k :给予某个 PID 一个讯号 (signal)
r :给予某个 PID 重新制订一个 nice 值。
q :离开 top 软件的按键。
2.3.1 进程实时查看 top 结果解析:
12:38:33 当前时间
up 50days 系统运行时间,格式为时:分
1 user 当前登录用户数
load average: 0.06, 0.60, 0.48
系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。
Tasks: 29 total 进程总数
1 running 正在运行的进程数
28 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
Cpu(s): 0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
2.3.2 进程查看 top结果解析:
2.3.3 进程查看 top结果解析:
PID 进程id PPID 父进程id RUS ER Real user name
UID 进程所有者的用户id
US ER 进程所有者的用户名
GROUP 进程所有者的组名
TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
PR 优先级
NI nice值。负值表示高优先级,正值表示低优先级
P 最后使用的CPU,仅在多CPU环境下有意义
%CPU 上次更新到现在的CPU时间占用百分比
TIME 进程使用的CPU时间总计,单位秒
TIME+ 进程使用的CPU时间总计,单位1/100秒
%MEM 进程使用的物理内存百分比
VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
CODE 可执行代码占用的物理内存大小,单位kb
DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
SHR 共享内存大小,单位kb
nFLT 页面错误次数
nDRT 最后一次写入到现在,被修改过的页面数。
S
进程状态。
D=不可中断的睡眠状态, R=运行, S=睡眠, T=跟踪/停止, Z=僵尸进程
COMMAND 命令名/命令行
WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
Flags 任务标志,参考 sched.h
2.4 进程查看 pstree:
选项与参数:
-A :各程序树之间的连接以 ASCII 字节来连接;
-p :并同时列出每个 process 的 PID;
-u :并同时列出每个 process 的所属帐号名称。
范例一:列出目前系统上面所有的程序树的相关性:
- [root@www ~]# pstree -A
- init-+-acpid
- |-atd
- |-auditd-+-audispd---{audispd} <==这行与底下一行为 auditd 分出来的子程序
- | `-{auditd}
- |-automount---4*[{automount}] <==默认情况下,相似的程序会以数字显示
- ....(中间省略)....
- |-sshd---sshd---bash---pstree <==就是我们命令运行的那个相依性!
范例二:承上题,同时秀出 PID 与 users
- [root@www ~]# pstree -Aup
- init(1)-+-acpid(4555)
- |-atd(18593)
- |-auditd(4256)-+-audispd(4258)---{audispd}(4261)
- | `-{auditd}(4257)
- |-automount(4536)-+-{automount}(4537) <==程序相似但 PID 不同!
- | |-{automount}(4538)
- | |-{automount}(4541)
- | `-{automount}(4544)
- |-sshd(4586)---sshd(16903)---bash(16905)---pstree(16967)
- |-xfs(4692,xfs) <==因为此程序拥有者并非运行 pstree 者!所以列出帐号
- ....(底下省略)....
# 在括号 () 内的即是 PID 以及该程序的 owner 喔!不过,由於我是使用root 的身份运行此一命令,所以属於 root 的程序就不会显示出来啦.
3.1 进程结束 kill:
kill -代号 PID
3.2 进程结束 killall -signal 命令名称:
[root@www ~]# killall [-iIe] [command name]
选项与参数:
-i :interactive 的意思,互动式的,若需要删除时,会出现提示字节给使用者;
-e :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的命令不能超过 15 个字节。
-I :命令名称(可能含参数)忽略大小写。
范例一:给予 syslogd 这个命令启动的 PID 一个 SIGHUP 的讯号
[root@www ~]# killall -1 syslogd
# 如果用 ps aux 仔细看一下,syslogd 才是完整的命令名称。但若包含整个参数,
# 则 syslogd -m 0 才是完整的呢!
范例二:强制终止所有以 httpd 启动的程序
[root@www ~]# killall -9 httpd
范例三:依次询问每个 bash 程序是否需要被终止运行!
[root@www ~]# killall -i -9 bash
Kill bash(16905) ? (y/N) n <==这个不杀! Kill bash(17351) ? (y/N) y <==这个杀掉! # 具有互动的功能!可以询问你是否要删除 bash 这个程序。要注意,若没有 -i 的参数, # 所有的 bash 都会被这个 root 给杀掉!包括 root 自己的 bash
4.1 进程优先级介绍:
具高优先权的 程序可以被优先调用,而较不重要的 运行次数较少。 如此一来 重要的程序就可以较快被完成啦!我们 Linux 给予程序一个所谓的『优先运行序 (priority, PRI)』, 这个 PRI 值越低代表越优先的意思。不过这个 PRI 值是由核心动态调整的, 使用者无法直接调整 PRI 值的。
由於 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 命令。
4.2 进程优先级 nice:
nice :新运行的命令即给予新的 nice 值
[root@www ~]# nice [-n 数字] command
选项与参数:
-n :后面接一个数值,数值的范围 -20 ~ 19。
范例一:用 root 给一个 nice 值为 -5 ,用於运行 vi ,并观察该程序!
- [root@www ~]# nice -n -5 vi &
- [1] 18676
- [root@www ~]# ps -l
- F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
- 4 S 0 18625 18623 0 75 0 - 1514 wait pts/1 00:00:00 bash
- 4 T 0 18676 18625 0 72 -5 - 1242 finish pts/1 00:00:00 vi
- 4 R 0 18678 18625 0 77 0 - 1101 - pts/1 00:00:00 ps
# 原本的 bash PRI 为 75 ,所以 vi 默认应为 75。不过由於给予 nice 为 -5 ,
# 因此 vi 的 PRI 降低了!但并非降低到 70 ,因为核心还会动态调整!
[root@www ~]# kill -9 %1 <==测试完毕将 vi 关闭 就如同前面说的, nice 是用来调整程序的运行优先顺序!这里只是一个运行的范例罢了! 通常什么时候要将 nice 值调大呢?举例来说,系统的背景工作中, 某些比较不重要的程序之进行:例如备份工作!由於备份工作相当的耗系统资源, 这个时候就可以将备份的命令之 nice 值调大一些,可以使系统的资源分配的更为公平!
4.3 进程优先级renice:
[root@www ~]# renice [number] PID
选项与参数:
PID :某个程序的 ID !
范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 10
- [root@www ~]# ps -l
- F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
- 4 S 0 18625 18623 0 75 0 - 1514 wait pts/1 00:00:00 bash
- 4 R 0 18712 18625 0 77 0 - 1102 - pts/1 00:00:00 ps
- [root@www ~]# renice 10 18625
- 18625: old priority 0, new priority 10
- [root@www ~]# ps -l
- F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
- 4 S 0 18625 18623 0 85 10 - 1514 wait pts/1 00:00:00 bash
- 4 R 0 18715 18625 0 87 10 - 1102 - pts/1 00:00:00 ps
如果要调整的是已经存在的某个程序的话,那么就得要使用 renice 了。使用的方法很简单, renice 后面接上数值及 PID 即可。因为后面接的是 PID ,所以你务必要以 ps 或者其他程序观察的命令去找出 PID 才行啊!
由上面这个范例当中我们也看的出来,虽然修改的是 bash 那个程序,但是该程序所触发的 ps 命令当中的 nice 也会继承而为 10 喔!了解了吧!整个 nice 值是可以在父程序 --> 子程序之间传递的呢! 另外,除了 renice 之外,其实那个 top 同样的也是可以调整 nice 值的!