1. 进程基本概述
进程是已启动的可执行程序的运行中实例。
/proc目录下以数字为名的目录,每一个目录代表一个进程,保存着进程的属性信息。每一个进程的PID是唯一的,就算进程退出了,其它进程也不会占用其PID。
1.1 进程的组成部分
已分配内存的地址空间
安全属性,包括所有权凭据和特权
程序代码的一个或多个执行线程
进程状态
1.2 进程的环境
本地和全局变量
当前调度上下文
分配的系统资源,如文件描述符和网络端口
1.3 进程的产生
现有的(父)进程复制自己的地址空间(fork)来创建一个新的(子)进程结构。
每个新进程分配有一个唯一的进程ID(PID),满足跟踪和安全性之需。PID与父进程ID(PPID)是新进程环境的元素。
任何进程可创建子进程。所有进程都是第一个系统进程的后代。RHEL7上,第一个系统进程是systemd。
通过fork例程,子进程继承安全性身份、过去和当前的文件描述符、端口和资源特权、环境变量,以及程序代码。随后,子进程可能exec其自己的程序代码。通常,父进程在子进程运行期间处于睡眠状态,设置一个在子进程完成时发出信号的请求(wait)。在退出时,子进程可能已经关闭或丢弃了其资源和环境,剩余的部分被称作僵停。父进程在子进程退出时收到信号而被唤醒,清理剩余结构,然后继续执行其自己的程序代码。
1.4 进程的分类
前台进程:与终端相关的进程,通过终端启动的进程
注意:也可 把在前台启动的进程送往后台,以守护模式运行
守护进程:daemon,与终端无关的进程(如内核),在系统引导过程中启动的进程
2.
进程状态
Excuting //运行态
Ready //就绪态,也可以称作睡眠态
Uninterruptible sleep //不可中断的睡眠。不可随时唤醒,只有当IO资源加载成功后才能唤醒
Interruptible sleep //可中断的睡眠。可随时唤醒
Zombie //僵尸进程。正常运行结束了,但是不释放占据的内存
Stopped //停止态,暂停于内存中,但不会被调度,除非手动启动之
进程睡眠的原因:
当一个执行中的进程,需要加载额外的IO资源的时候,由于IO设备的速度太慢,所以会转入睡眠状态等待,交出CPU给其他进程,以免浪费剩余执行时间
3. 进程优先级
-
进程优先级范围:0-139,数字越小,优先级越高
-
0-99:实时优先级,内核调整
-
100-139:静态优先级,用户可控制
-
进程优先级高的特点:
-
获得更多的CPU运行时间
-
更优先获得CPU运行的机会
要修改进程的优先级可以通过调整进程的nice值来实现,nice值越小,优先级越高:
nice值的范围是(-20,19),-20对应100,19对应139
3.3 相对优先级
由于不是每种进程都与其他进程同样重要,可告知调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的调度策略称为SCHED_OTHER(也称为SCHED_NORMAL),但还有一些其他策略可用于不同的目的。
由于并非所有进程都以同样的方式创建,可为采用SCHED_NORMAL策略运行的进程指定相对优先级。此优先级称为进程的nice值。一个进程可以有40种不同级别的nice值。
这些nice级别的范围是从-20到19。默认情况下,进程将继承其父进程的nice级别,通常为0
nice级别越高,表示优先级越低(该进程容易将其CPU使用量让给其他进程)
nice级别越低,表示优先级越高(该进程更加不倾向于让出CPU)
如果不存在资源争用(例如当活动进程数少于可用CPU核心数时),即使nice级别高的进程也将仍使用它们可使用的所有可用CPU资源。但当请求CPU时间的进程数超过可用核心数时,nice级别较高的进程将比nice级别较低的进程收到更少的CPU时间
3.4 nice级别与权限
为很占CPU资源的进程设置较低的nice级别可能会对同一系统上运行的其他进程的性能造成负面影响,所以仅允许root用户设置负nice级别以及降低现有进程的nice级别。
普通非特权用户仅允许设置正的nice级别。只能对现有进程提升nice级别,而不能降低nice级别。
3.5 进程优先级调整
进程优先级调整:调整nice值
//调整已经启动的进程的nice值:
renice NI PID(例:renice 3 3704)
//在启动时指定nice值:(-20,19)
nice -n NI COMMAND
4. 进程管理命令
Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中
4.1 ps
ps(process state)命令用于列出当前的进程。可以显示详细的进程信息,包括:
用户识别符(UID),它确定进程的特权
唯一进程识别符(PID)
CPU和已经花费的实时时间
进程在各种位置上分配的内存数量
进程的位置STDOUT,称为控制终端
当前的进程状态
ps支持三种选项格式:
UNIX(POSIX)选项,可以分组但必须以连字符开头
BSD 选项,可以分组但不可与连字符同用
GNU 长选项,以双连字符开头
ps(process state),显示进程信息。注意事项:
加了[]中括号的,表示内核线程,通常位于顶部
exiting或defunct表示僵尸进程
//常用选项:
a //显示所有与终端有关的进程
u //显示进程是由哪个用户启动的
x //显示所有与终端无关的进程
-e //显示所有进程,与-A效果相同
-l //以长格式显示
-F //显示更详细的完整格式的进程信息
-f //显示更详细的完整格式的进程信息
-H //以进程层级格式显示进程相关信息
-o //根据自己的需要选择要显示的字段
[root@localhost ~]# ps -o pid,comm,ni //表示只显示进程号,命令,nice值三个字段
PID COMMAND NI
8828 bash 0
9844 ps 0
//aux结果解析:
VSZ //Virtual memory SiZe,虚拟内存集
RSS //ReSident Size,常驻内存集
STAT //进程状态
TIME //运行时的累积时长
//ps命令结果解析:
NI //nice值
PRI //优先级
PSR //进程运行在哪个CPU核心上
RTPTRIO //实时优先级
C //运行的CPU编号
STIME //进程的启动时间
VSZ //Virtual memory SiZe,虚拟内存集
RSS //ReSident Size,常驻内存集
STAT //进程状态
TIME //运行时的累积时长
4.2 pstree
pstree用于显示当前系统上的进程树
[root@localhost ~]# pstree
systemd─┬─NetworkManager─┬─dhclient
│ └─2*[{NetworkManager}]
├─VGAuthService
├─atd
├─auditd───{auditd}
├─crond
├─dbus-daemon
├─firewalld───{firewalld}
├─irqbalance
├─login───bash
├─lvmetad
├─master───qmgr
├─polkitd───5*[{polkitd}]
├─rhnsd
├─rhsmcertd
├─rsyslogd───2*[{rsyslogd}]
├─sshd───sshd───bash───pstree
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
└─vmtoolsd───{vmtoolsd}
4.3 pgrep
以grep风格指定只显示哪些进程,在当前系统中找符合某些特性的进程。只显示进程号
[root@localhost ~]# pgrep atd
1387
[root@localhost ~]# pgrep sshd
1105
8826
[root@localhost ~]# ps -ef|grep sshd
root 1105 1 0 08:44 ? 00:00:00 /usr/sbin/sshd -D
root 8826 1105 0 09:48 ? 00:00:00 sshd: root@pts/0
root 9908 8828 0 16:42 pts/0 00:00:00 grep --color=auto sshd
4.4 pidof
根据进程名查找其PID号
[root@localhost ~]# pidof sshd
8826 1105
[root@localhost ~]# pidof atd
1387
4.5 vmstat
虚拟内存状态查看命令
//语法:vmstat [options] [delay [count]]
//例:
vmstat 2 //表示每2秒刷新一次
vmstat 2 5 //表示每2秒刷新一次,刷新5次后退出
//常用的选项:
-s //显示内存的统计数据
[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
1 0 0 576992 3388 271316 0 0 2 1 15 13 0 0 100 0 0
procs:
r(running) //表示等待运行的队列长度,也即等待运行的进程的个数
b(block) //表示阻塞队列长度,也即处于不可中断睡眠态的进程个数
memory:
swpd //交换内存的使用总量
free //空闲物理内存总量
buffer //用于buffer的内存总量
cache //用于cache的内存总量
swap:
si(swap in) //表示从物理内存有多少页面换进swap,也即数据进入swap的数据速率(kb/s)
so(swap out) //表示从swap有多少页面换进物理内存,也即数据离开swap的数据速率(kb/s)
io:
bi(block in) //表示磁盘块有多少个被调入内存中,也即从块设备读入数据到系统的速率(kb/s)
bo(block out) //表示有多少个磁盘块从内存中被同步到硬盘上去了,也即保存数据至块设备的速率(kb/s)
system:
in( interrupts) //表示中断的个数,也即中断速率(kb/s)
cs(context switch) //表示上下文切换的次数,也即进程切换速率(kb/s)
CPU:
us //表示用户空间
sy //表示内核空间
id //表示空闲百分比
wa //表示等待IO完成所占据的时间百分比
st //表示steal,被虚拟化技术偷走的时间(比如运行虚拟机)
5. 控制作业
5.1 作业与会话
作业控制是shell的一种功能,它允许单个shell实例运行和管理多个命令。
作业与在shell提示符中输入的每个管道相关联。该管道中的所有进程均是作业的一部分,并且是同一个进程组的成员。(如果在shell提示符中仅输入了一条命令,则这条命令可视为命令的最小管道。该命令将是该作业的唯一成员)
一次只能有一个作业从特定终端窗口读取输入和键盘生成的信号。属于该作业的进程是该控制终端的前台进程。
该控制终端的后台进程是与该终端相关联的任何其他作业的成员。终端的后台进程无法从终端读取输入或接收键盘生成的中断,但可以写入终端。后台中的作业可能已停止(暂停),也可能正在运行。如果某个正在运行的后台作业尝试从终端读取内容,则该作业将自动暂停。
每个终端是其自身的会话,并且可以具有一个前台进程和多个独立的后台进程。一个作业只能属于一个会话,也就是属于其控制终端的会话。
5.2 作业分类
Linux作业分为前台作业与后台作业两种。其各自的特点如下:
前台作业:通过终端启动,且启动后一直占据了命令提示符
后台作业:可以通过终端启动,但启动之后,释放命令提示符,后续的操作在后台完成
此类作业虽然被送往后台运行,但其依然与终端相关。如果希望送往后台后,剥离与终端的关系需要执行(nohup COMMAND &)
5.3 在后台运行作业
//在命令后跟上&符号可以生成一个后台作业
[root@localhost ~]# sleep 1000 &
[1] 1819
//jobs命令用于显示当前所有的后台作业
[root@localhost ~]# jobs
[1]+ Running sleep 1000 &
//fg命令用于将后台作业调至前台运行
[root@localhost ~]# fg
//当只有一个后台作业时,直接使用fg命令,不跟任何参数即可将后台作业调至前台运行,但是当有多个作业时则必须跟上%+作业号,也就是上面命令执行结果中以[]括起来的数字。
[root@localhost ~]# jobs
[1]- Running sleep 1000 &
[2]+ Running sleep 500 &
[root@localhost ~]# fg %1
//使用ctrl+z可将前台进程发送到后台,此时作业将处于停止状态
[root@localhost ~]# fg %1
sleep 1000
^Z
[1]+ Stopped sleep 1000
//使用bg命令+作业号可使后台已停止的作业重新运行
[root@localhost ~]# bg %1
[1]+ sleep 1000 &
[root@localhost ~]# jobs
[1]- Running sleep 1000 &
[2]+ Running sleep 500 &
//kill加上作业号可以手动杀死指定作业
[root@localhost ~]# jobs
[1]- Running sleep 1000 &
[2]+ Running sleep 500 &
[root@localhost ~]# kill %1
[1]- Terminated sleep 1000
[root@localhost ~]# jobs
[2]+ Running sleep 500 &
//jobs命令的结果中
+ //命令将默认操作的作业
- //命令将第二个默认操作的作业
6. 进程间通信
进程间通信(IPC:Inter Process Communication)
进程间通信方式:
同一主机
共享内存
信号:Signal
不同主机
rpc:remote procecure call
基于socket实现进程间通信
7. 使用信号控制进程
信号是传递至进程的软件中断。信号向执行中的程序报告事件。生成信号的事件可以是错误或外部事件(如I/O请求或计时器过期),或者来自于明确请求(如使用信号发送命令)
下表列出了系统管理员用于日常进程管理的基本信号。请通过短名称(HUP)或正确名称(SIGHUP)指代信号。
指定一个信号的方法:
信号号码(数字标识):kill -1
信号完整名称:kill -SIGKILL
信号简写名称:kill -TERM或kill -KILL或kill -INT或kill -HUP
基本进程管理信号
8.2 实时进程监控
top用于实现全屏动态显示系统信息
//常用选项:
-d //设置延迟时长,top -d 1表示每隔1秒刷新一次,默认每隔5秒刷新
-b //批模式翻屏显示,默认只实时显示一屏,若要显示后面的进程信息则可使用-b选项,与-n #合用,可指定显示翻#屏
[root@localhost ~]# top -b -n 1
top - 16:58:44 up 8:14, 2 users, load average: 0.00, 0.01, 0.05
Tasks: 178 total, 1 running, 177 sleeping, 0 stopped, 0 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 : 999720 total, 575768 free, 148504 used, 275448 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 670936 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 190888 3776 2504 S 0.0 0.4 0:01.14 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.04 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:00.83 rcu_sched
load average:1分钟,5分钟,15分钟
load average //CPU队列中等待运行的任务的个数
cpu(s):多颗CPU平均负载,按1键显示每颗CPU平均负载。
us //表示用户空间;
sy //表示内核空间;
ni //表示调整nice值,CPU占用的比率;
id //表示空闲百分比;
wa //表示等待IO完成所占据的时间百分比;
hi //表示hard interrupt,硬件中断占据的时间百分比;
si //表示软中断占据的时间百分比;
st //表示steal,被虚拟化技术偷走的时间(比如运行虚拟机)
PR //优先级
NI //nice值
VIRT //虚拟内存集
RES //常驻内存集
SHR //共享内存大小
S //进程状态
//top命令交互式子命令:
M //根据驻留内存大小进行排序,默认根据CPU百分比排序
P //根据CPU使用百分比进行排序
T //根据累计时间(占据CPU时长)进行排序
l //是否显示平均负载和启动时间
t //是否显示进程和CPU状态相关信息
m //是否显示内存相关信息
c //是否显示完整的命令行信息
q //退出top命令
k //终止某个进程
1 //显示所有CPU的信息
s //修改刷新时间间隔