第十五节.进程管理及系统信息查询

最后更新于 2021-11-18 408 次阅读


Contents hide

1.进程与程序

(1)什么是进程?

当我们在Linux系统中【执行一个程序或一个命令来触发一个事件】时,系统会将这个【事件】定义为一个进程,并给予这个进程一个ID,称其为【PID】,同时根据触发进程的用户与相关属性关系,给予这个PID一组有效的权限设置。

换句话说,程序被执行后,执行者的权限与属性、程序的代码与所需的数据都会被加载到内存当中,操作系统会给予这个内存中的单元一个标识符【PID】,进程也可以说一个正在运行的程序。

所以,当我们以不同的身份登录我们的linux系统执行bash时,系统为我们分配的PID其实是不一样的。

(2)父进程与子进程

这个相关的概念我们在BASH里export环境变量的内容里有提到过,我们已知在一个bash中,运行另外一个bash时(执行命令),就会从父进程,切换到父进程下边的子进程去,那么这时,系统也会为我们的子进程分配一个【PID】。

而父进程与子进程两个进程彼此之间是有相互联系的,如果我们想查看一个进程是不是另外一个进程的子进程,那我们就可以通过【PPID】来进行判断,如果这个进程的【PPID】是另外一个进程的【PID】,则这个进程就是另外一个进程的子进程

父进程与子进程的ID关系

如图,ps的【PPID】和bash的【PID】一致,我们就可以判断ps是bash下引出的子进程,因为毕竟我们是在bash的环境下执行的ps命令嘛。。

(3)程序调用的流程:fork和exec

在linux中,父进程和子进程之间的程序调用通常称为fork(复制)和exec(执行)。

具体执行一个子进程时,系统是先fork一个和父进程一致的子进程,然后子进程再通过exec的方式来执行实际要执行的进程,最终就变成了一个新的子进程。

用课本的图就可以表达成这样

父进程与子进程的关系

先fork父进程,并引入PPID这个进程标识符,子进程的PPID继承父进程的PID,然后再另外创建一个新的标识符PID,接着执行(exec)新的程序名qqq,变成最终的子进程。

(4)常驻在内存的进程:系统或网络服务

在Linux中,有许多系统(atd、crond)或网络服务(apache、named、postfix、vsftpd)是一直在后台中运行的,这类进程我们通常称为【常驻在内存内的进程】。

常驻在系统内存中的进程通常都是负责一些系统所提供的功能以服务用户的各项任务,因此这些进程被我们成为:服务(daemon),Linux为了让我们能够简单的区分服务进程,所以一般服务(daemon)进程文件名后边都会添加一个字母【d】,类似于sshd、vsftpd、httpd等

首先我们要明确一个概念,任务管理是建立在单一终端的bash shell下的,也就是说我们是在一个终端下(例如一个远程ssh链接)进行着一个多任务操作(例如一边复制、一边查找文件、一边进行vim编辑)。

就有点类似于windows里的多窗口操作,在一个用户的登录系统下进行着多个活动,我们administrator这个用户是没办法管理laoju这个用户中的多任务操作的。同样在linux系统中,我们没法用任务管理的的方式由tty1的环境去管理tty2的bash。

执行bash的任务管理的限制:

1.任务管理触发的进程必须属于你自己的这个shell,也就是你这个shell触发的子进程。

2.前台(foreground):可以控制与执行命令这个环境称为前台的任务。

3.后台(background):可以自动执行的任务,不可以使用【ctrl+ c】取消任务,但是可以使用【fg】、【bg】来调用任务。

4.后台执行的任务不能等待terminal和shell的输入(input),也就是不能和用户进行交互。

(2)如何进行任务管理(job control)?

已知,bash只能管理自己的任务而不能管理其他bash的任务,也就是你不能把别人bash下的job拿过来执行,然后job在后台本身是有两种状态,分别是【暂停】和【运行】,接下来我们就来分析实际执行job管理的命令有哪些。

①.&:让程序在后台运行

在命令的后面,跟上符号【&】,可以将命令放在后台执行。但是默认如果不使用数据重定向,程序的标准输出还是会在前台显示

例如我想打包/etc这个文件夹,但我又不想其在前台进行打包输出文字影响我前台任务的进行,于是我就可以输入命令:

tar -cjv -f /tmp/etc.tar.bz2 /etc &>/dev/null &

可见再输入命令执行后,系统返回了一个【[1] 3174】值给我们,这里的【[1]】代表着【任务号码(job number)】,而后边的【3174】则代表着该命令触发的进程的【PID】。

命令在后台执行完毕后,系统会返回一个任务完成的确认信息。

后台任务执行完毕的返回值

②.ctrl+z:让程序在后台暂停

当我们想暂停前台正在进行的工作,切换到别的工作时,我们可以使用【ctrl+z】这个组合键将前台的工作暂停并放到后台去。

例如当我在使用vim查看一个文档时,我想去输入某个命令查询消息的话,就可以使用【ctrl+z】暂停vim

③.jobs:查看当前后台所有的任务

输入【jobs】可以查看当前bash后台所有的任务,任务数字后的【+】表示最新放入后台的任务,【-】表示第二放入后台的任务,如果有三个任务以上,则不会显示加减号

命令格式:jobs 【-l r s】

常用参数:

-l:不仅列出【任务数字】,还要列出对应的进程【PID】

-r:仅列出正在后台运行(running)的任务

-s:仅列出在后台暂停(stop)的任务

④.fg:恢复后台的任务到前台运行

命令格式:fg %jobnumber

将后台的任务恢复到前台运行,任务数字前的【%】可有可无

一般配合【jobs】命令查询后台的正在运行的任务,在跟上你想恢复的任务数字,如果不带任务数字输入【fg】则表示恢复最近一个放到后台的程序

⑤.bg:让任务在后台继续执行

命令格式:bg %jobnumber

让在后台暂停的任务继续在后台执行

例如我先打包/etc这个文件,然后在打包的过程中输入【ctrl+z】将任务放在后台暂停,然后输入【bg】命令让其在后台继续运行

bg命令让任务在后台执行

⑥.kill与killall:管理后台当中过的任务

使用【kill】命令能够对后台中的任务或进程发送信号来进行管理,可以重启任务或直接强制终止任务。

默认情况下,kill后边直接接的是进程或任务的【PID】,如果想要接【jobnumber】的话,就需要跟上【%】号

若是我们想不找PID,而直接输入进程的名字来管理进程的话,就可以使用【killall】命令,这命令会将当前系统内是这个名字的进程全部处理掉

命令格式:kill 【-l】 【-signal】 PID/%jobnumber

killall 【-i I】 进程程序名

例如:kill -9 %2

killall -9 -i httpd

常用参数:

kill:

-l:查看当前系统下的所有kill信号

kill -l命令演示

killall:

-i:进入交互模式,在每个进程处理之前都询问用户

-I:忽略进程名字(可能包含参数)的大小写

常用的signal:

-1:重启任务或进程

-HUP:重新加载进程的配置文件并重启进程

-2:代表由键盘输入【ctrl+c】同样的操作

-9:强制终结某个任务或进程

-15:以正常的方式来关闭某个任务或进程

(3)脱机命令管理(nohup)

如果你想让一个外部命令在bash后台运行,并且你注销系统或断开ssh连接也不会让其终止的话,就可以使用【nohup】这个命令。

命令格式:nohup 【命令与参数】 &

如果想在前台运行就去掉符号【&】,该命令执行后的输出结果会保存在家目录的~/nohup.out中

3.进程管理(process)

(1)查看系统进程

①.ps命令静态查看进程

命令格式:ps 【-la】【aux】【axjf】

常用参数:

-l:查看当前bash的进程的详细信息

ps -l参数演示

-A:所有的进程均显示出来(有点类似aux,但是配合-l显示的信息会更多)

ps -A参数演示

-a:查看不与终端有关的所有进程

ps -a参数演示

aux:也是查看所有系统的进程,但是更加的详尽

ps aux命令演示

axjf:和pstree命令类似,可以查看系统的进程树

其中,a与x常常一起使用,获取更详尽的信息,j是输出任务的格式,f是可以做一个更完整的输出

ps axjf参数演示

其中,我们以下边这个【ps -l】的结果为例,分析各个显示字段的意义

ps -la参数演示
Ⅰ.F(进程标识)

表示这个进程的执行权限

【4】代表这个进程是root权限;

【1】则代表这个子进程仅执行复制(fork),而没有实际执行(exec)

Ⅱ.S(进程状态)

表明这个进程当前的状态

【R(Running)】:表明进程正在运行;

【S(Sleep)】:表明进程正在休眠;

【D】:不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况(ex>打印);

【T(Stop)】:该进程处于停止(stop)状态,可能是在任务控制(后台暂停)或跟踪(traced)状态;

【Z(Zombie)】:僵尸状态,进程已经终止但是无法被删除至内存外;

Ⅲ.UID

该进程所属的USER的UID,这里属于root,所以是0

Ⅳ.PID

该进程所属的PID

Ⅴ.PPID

该进程父进程的PID

Ⅵ.C

代表CPU使用率

Ⅶ.PRI/NI(priority/nice)

该进程被CPU执行的优先级,越小越优先,但是pri一般不能自行修改,我们只能通过更改nice的值来调整优先级

Ⅷ.ADDR/SZ/WCHAN

都与内存有关

ADDR是【kernel function】,说明该进程在内存的哪个部分,如果是个running进程,会显示【-】

SZ说明该进程吃掉了多少内存

WCHAN表示目前进程是否运行,如果进程正在运行,则会显示【-】

Ⅸ.TTY

登录者的终端位置,若为远程登录,则显示动态终端端口名称(pts/n)

Ⅹ.TIME

该进程实际运行占用CPU的时间

ⅩⅠ.CMD

表示该进程是由什么命令触发的

然后我们以【ps aux】的结果来对比【ps -l】的结果,来看看有没有什么不一样的字段

详解ps aux各个字段的意义

区别字段:

ⅩⅡ.%CPU

该进程使用掉的CPU资源的百分比

ⅩⅢ.%MEM

该进程使用掉的内存资源的百分比

ⅩⅣ.VSZ

该进程使用掉的虚拟内存百分比

ⅩⅤ.RSS

该进程使用掉的实际内存百分比

ⅩⅥ.TTY

该进程是在哪个终端上运行,若与终端无关则显示【?】,如果是在本机上登录则显示【tty】,如果是网络终端登录,则显示【psy/n】

②.pstree命令查看系统进程树

如果我们想查询一个进程的来源,想查看其父进程和父父进程的时候,就可以使用【pstree】命令来查询系统的进程树

但是有些系统里不一定有【pstree】这个命令,所以我们需要安装,安装命令为【yum install -y psmisc】

命令格式:pstree 【-p u】

常用参数:

-p:列出进程树的同时,也将相应的【PID】列出来

pstree -p参数演示

-u:列出进程树的同时,也将相应的进程帐号所属列出来

pstree -u参数演示

③.top命令动态查看系统进程情况

使用【top】命令可以动态的查看系统各个进程占用系统资源的情况,也可以选择按照用户想要的排序方式进行排序。

命令格式:top 【-d 秒数】 【-b n p】

常用参数:

-d:后面接秒数,表示多少秒刷新一次数据,默认为5秒

-b:以批量的方式执行top,还有更多的参数可以配合使用,通常会搭配数据流重定向来将批量的输出结果输出为文件

-n:与-b搭配,后面接数字n,表示想要执行top的次数,也就是输出几次

例如:top -bn 3

-p:后面接某个PID,表示指定某个PID来执行检测

例如:top -d 3 -p 12910

top -p 指定PID进行监测

执行top后可以使用的按键命令:

?:查看可用的按键命令

P:以CPU利用率来从上到下进行排序

P 以CPU利用率进行排序

M:以内存使用率来从上到下进行排序

M 内存占用率排序

N:以PID来排序

N 以PID大小进行排序

T:以该进程使用的CPU的累积时间来进行排序

T 以进程使用CPU的总时间来进行排序

k:给予某个PID一个signal

选定PID
发送signal

r:更改某个pid的nice值(优先值)

选定PID
更改nice值

q:退出top

我们以课本上的内容来对top的各个字段做个解释

top各个参数意义的详解

(2)进程的执行顺序

linux系统进程在执行的时候,是有一个执行的优先值顺序的,这个执行的优先值顺序决定了进程被CPU处理的顺序。

跟进程的处理优先值有关的字段为:priority和nice

pri和ni的演示

由于priority的值由系统计算分配所确定,我们无法更改,所以我们只能通过更改Nice的值来更改进程优先值。

Nice值越小越优先,并且更改的父进程的Nice值也会影响到子进程的Nice值,也就是说Nice值是可以被继承的。

Nice处理值的注意事项:

※nice的值可更改范围为【-20~19】

※root用户可以任意更改自己或他人进程的nice值,范围同为【-20~19】

※普通用户只能修改属于自己的进程的nice值,范围为【0~19】

※一般用户只能将nice往大了去修改,比如原来nice值为5,那么只能更改成比5更大的数值

Nice的更改方式:

①.top命令中进行修改

进入top命令后,按【r】键后输入你想要更改nice值的PID号,然后输入你想要更改的nice值。

这里我将nice改成了5

使用top命令修改nice值

可见priority的值也产生了变化,也就是说priority的值原本就是priority+nice的和

②.nice:创建新命令时就进行更改

命令格式:nice 【-n 数字】 command

例如:nice -n -5 sh /tmp/pi.cal.sh

可见,nice值变成了-5,pr值也变成了15

③.renice:更改已执行命令的nice值

命令格式:renice 【数字】 PID

例如:renice -5 16371

比如我先行运行一个脚本,该脚本PID为16371,默认pri为80,默认NI值为0

我使用renice命令将nice值改为【-5】

4.查看系统信息

(1)free:查看系统内存使用情况

使用free可以查看系统当前的内存使用情况,在linux系统中,哪怕只开了很少的服务,然后物理内存被占用完,也是十分正常的情况,但是如果是swap内存被占用到20%以上,就要考虑检查下系统是出现了什么问题了

命令格式:free【-h | -b | -k | -m | -g |】【-s 秒速 -c 执行的次数】【-t】

例如:free -h -s 2 -c 5 -t

常用参数:

-h:让系统自己指定显示的单位

free -h更改显示单位

-b、-k、-m、-g:分别是让系统已Byte、KByte、MByte、GByte的单位来显示结果

free -k参数演示

-s:后面接秒数,表示让free以n秒为单位进行一次数据的刷新

-c:常接在-s后边,表示指定free刷新的次数

-t:将物理内存和Swap交换内存的总和(total)也一并列出

free -s 1 -c 2 -t参数演示

其中,【total】字段代表内存总大小,【used】字段代表已使用的内存,【free】字段代表未使用的内存,【shared、buff/cache】代表已被使用的量中用于缓冲及缓存的内存,其在系统繁忙时,可以被释放而重新利用,【available】就代表其可以被释放的值。

(2)uname:查看系统内核及硬件信息

命令格式:uname 【-a】

(3)uptime:查看系统运行时间

(4)netstat:查看系统网络服务及socket进程信息

netstat不仅可以查看系统提供的网络服务的端口信息和IP信息,还可以查看系统上socket文件的相关信息。

这里所提到的socket文件,是linux中进程之间沟通的桥梁,进程与进程之间可以通过socket来沟通信息。

但是我们这里着重来看netstat的网络信息部分。

命令格式:netstat 【-a t u n l p 】

参数详解:

-a:将当前服务器上所有的网络连接、监听端口、socket信息全列出

netstat -a参数演示

-t:仅列出tcp连接的网络信息

netstat -t参数演示

-u:仅列出udp连接的网络信息

-n:不以进程的服务名称,仅以端口号(port number)显示

如果不加参数n的话是显示该端口对应的服务名称

不加-n参数时的结果演示

但是加入了参数n后,就是显示端口号了

加-n参数后显示端口号

-l:列出当前正在进行网络监听(listen)的服务

netstat -l参数演示

-p:列出系统进程服务的进程PID及服务的名字

netstat -p参数显示

①.netstat网络信息字段的意义分析

我们取香港(猪云)的服务器tcp连接来进行字段意义分析

netstat网络字段分析
Ⅰ.proto

表明该网络连接使用的协议,tcp代表tcp协议,udp代表udp协议,tcp6代表ipv6的tcp。

有些服务在linux上默认显示tcp6而不显示tcp,但这并不意味着我们系统只监听ipv6地址,有时候ipv6的socket也是能监听ipv4地址的请求的

Ⅱ.Recv-Q

Recv-Q网络接收队列

表示收到的数据已经在本地接收缓冲,但是还有多少没有被进程取走,如果接收队列Recv-Q一直处于阻塞状态,可能是遭受了拒绝服务 denial-of-service 攻击。

Ⅲ.Send-Q

Send-Q网络发送队列

表示对方没有收到或者没有确认的数据包数量(ack),这些数据包存在本地缓存区中

如果发送队列Send-Q不能很快的清零,可能是有应用向外发送数据包过快,或者是对方接收数据包不够快。

Recv-Q和Send-Q这两个值通常应该为0,如果不为0可能是有问题的。packets在两个队列里都不应该有堆积状态。可接受短暂的非0情况

Ⅳ.Local Address

网络服务的本地监听的地址和端口

Ⅴ.Foreign Address

远程主机的地址和端口情况

Ⅵ.state

网络连接的状态,有establish(建立),Listen(监听),Time_wait(主动发起关闭连接等待对方确认中),close_wait(被动等待关闭连接)

②.netstat进程socket信息字段的意义分析

在新的Linux发行版中,使用socket(套接字)来进行窗口接口的连接与沟通

netstat socket信息字段分析
Ⅰ.proto

一般就是unix

Ⅱ.RefCnt

连接到此socket的进程数量

Ⅲ.Flags

连接的标识

Ⅳ.Type

socket存取的类型,分为确认连接(tcp)的STREAM和不需要确认连接(udp)的DGRAM

Ⅴ.State

socket的状态,若为CONNECTED这表示多个进程之间已经建立了连接,若为LISTENING则表示该socket正在进行监听中

Ⅵ.PATH

连接到此socket的相关进程的路径信息,或是相关进程数据输出的路径

(5)vmstat:查看系统资源的使用清理

使用vmstat可以监测系统的进程、内存、磁盘读写I/O数据、系统项目、CPU项目的使用情况

命令格式:vmstat 【-S 显示单位】【(n)刷新间隔 (N)刷新次数】 【-d】

常用参数:

-S:切换显示数据的单位,有k/m等切换Bytes的容量

例如:vmstat -S m 2 3 (以MBytes为单位,2秒刷新一次数据,刷新三次)

然后我们根据显示的结果来分析一下它各个字段的意思

①.procs:进程字段

r:等待运行中的进程数量

b:不可被唤醒的进程数量

这个字段的数值越大,就代表系统越忙碌,因为有很多进程在后台等待着运行

②.memory:内存字段

swap:交换内存(虚拟内存)的使用量

free:未被使用的内存容量

buff:用户缓冲存储器

cache:用于高速缓存

③.swap:内存交换分区字段

si:从磁盘中(虚拟内存中)取出的进程的数量

so:由于物理内存不够而放入磁盘(虚拟内存)中的无用进程的数量

如果si/so的值过大,则代表物理内存不够,虚拟内存的使用量大,系统性能很差

④.io:磁盘读写项目字段

bi:读取磁盘数据的区块数量

bo:写入到磁盘数据的区块数量

bi/bo的值越大,则代表系统越忙碌

⑤.system:系统项目字段

in:每秒被中断的项目次数

cs:每秒执行的事件切换次数

in/cs的值越大,则代表系统与外接设备的沟通就越频繁,这些接口设备包括磁盘、网卡等

⑥.CPU:CPU设备项目

us:非内核层的CPU使用率(运行一些服务、脚本的时候的cpu使用率)

sy:内核层的CPU使用率

id:闲置的CPU使用率

wa:等待IO状态消耗的CPU使用率

st:被虚拟机所使用的CPU使用率

(6)fuser:查看当前文件或文件夹正在被哪个进程所使用

我们有时候如果在卸载一个文件或文件系统时,系统弹出【device is busy】的话,我们就可以判定当前文件或文件系统正在被某个进程所使用中。

若是我想查找到底是被哪个进程所使用的话,就需要【fuser】这个命令进行查询。

命令格式:fuser 【-u m v】【-k i 【-signal】】 文件/文件夹

例如:fuser -u -ki -9 /etc/v2ray-agent/xray/xray

常用参数:

-u:除了列出进程PID以外,再列出进程的拥有者

fuser -u列出进程的拥有者

-m:查看当前文件系统正在被多少个进程所使用,后面接的那个文件名会主动地上提到该文件系统的最顶层,对umount不成功很有效(umount命令为卸载文件系统)

-v:可以一并列出使用该文件的进程的用户所属、PID、权限、以及执行的命令

fuser -v列出详尽数据

-k:后续搭配-signal信号,可以控制使用该文件的进程,不跟-signal的话则默认为【-9】

-i:搭配-k使用,再对进程做出操作前先询问用户

(7)lsof:找出某个进程正在使用的文件

(8)pidof:找出某个正在执行的进程的PID

找寻一个服务名对应的进程PID,例如systemctl

命令格式:pidof 服务名

pidof 命令演示

·