这个进程的状态(STAT),主要的状态有:
- R(Running):该进程正在运行中(running) 或是可运行的(runnable)。
- S(Sleep):进程处于可被唤醒(signal)的睡眠状态,也即所谓空闲状态(idle)。这种状态一般是进程主动进入的。
- D:进程处于不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况(例如打印)。这种状态一般是进程被动进入的。
- T(Stopped):停止状态,可能是在任务控制(后台暂停)或跟踪(traced)状态。
- Z(Zombie):僵尸状态(即所谓defunct),进程已经终止但却无法被删除至内存外。
UID/PID/PPID:代表进程被该UID所拥有/进程的PID号码/此进程的父进程PID号码。
C:代表CPU使用率,单位为百分比。
PRI/NI:Priority/Nice的缩写,代表此进程被CPU所执行的优先级,数值越小代表该进程越快被CPU执行。详细的PRI与NI将在下一小节说明。
ADDR/SZ/WCHAN:都与内存相关,ADDR是kernel function,指出该进程在内存的哪个部分,如果是个running的进程,一般就会显示-
;SZ代表此进程用掉多少内存;WCHAN表示目前进场是否运行,同样的,若为-
表示正在运行中。
TTY:登录者的终端位置,若为远程登录则使用动态终端接口名称(pts/n
)。
TIME:使用CPU的时间,注意是进程实际花费CPU的时间,而不是运行时间。关于这两个时间之间的区别可参见我的博客《Python:对程序做性能分析及计时统计》
CMD:就是command的缩写,表示触发此进程的命令是什么。
所以你看到的ps -l
输出信息中,它说明的是:bash进程属于UID为0的用户,状态为睡眠(Sleeping),之所以为睡眠,是因为它触发了ps
(状态为Running)。此进程的PID是42331,执行优先顺序为80,执行bash所获取的终端接口为pts/0
。运行状态为等待(wait)。
接下来我们用ps auxf
列出类似进程树的进程显示:
(base) root@qi:~/Orion-Orion# ps -auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4504 48 pts/0 Ss 2022 0:01 sh /root/start.sh
root 7 0.0 0.0 65520 420 ? Ss 2022 0:07 /usr/sbin/sshd
root 38677 0.0 0.0 93284 7412 ? Ss 07:55 0:00 \_ sshd: root@notty
root 38687 0.0 0.0 9756 2824 ? Ss 07:55 0:00 | \_ bash
root 38765 0.0 0.0 4504 1712 ? S 07:55 0:00 | \_ sh /root/.vscode-server/bin/b7886d7461186a5
root 41898 0.1 0.0 661960 58144 ? Sl 10:38 0:06 | | \_ /root/.vscode-server/bin/b7886d7461
root 42331 0.0 0.0 20060 3788 pts/312 S 10:40 0:00 | | \_ bash
root 43592 0.0 0.0 36276 3248 pts/312 R+ 11:41 0:00 | | \_ ps -auxf
...
root 39717 0.0 0.0 93648 7608 ? Ss 08:40 0:02 \_ sshd: root@notty
root 39727 0.0 0.0 9752 2924 ? Ss 08:40 0:00 | \_ bash
root 43493 0.0 0.0 4376 672 ? S 11:40 0:00 | \_ sleep 180
root 41362 0.0 0.0 93296 7360 ? Ss 10:33 0:01 \_ sshd: root@notty
root 41372 0.0 0.0 9752 2824 ? Ss 10:33 0:00 \_ bash
root 43492 0.0 0.0 4376 700 ? S 11:39 0:00 \_ sleep 180
root 8 0.0 0.0 20052 264 pts/0 S+ 2022 0:00 /bin/bash
因为我是用ssh网络连接进入服务器来执行一些测试的,可以看出进程之间是相关性的。从上面的例子来看,我是通过sshd
提供的网络服务获取的一个进程,该进程提供bash给我使用,而我通过bash再去执行VSCode-Server服务启动脚本,以运行VSCode-Server服务进程,然后该进程再提供给我一个bash, 我通过这个bash再去执行ps auxf
(疯狂套娃哈哈哈)。
这里说一个题外话,sshd
进程是我们前面提到的deamon,是不能随意杀掉的哦! 杀掉了不仅你会马上断开连接,下次再用ssh连你也连不上了。
除了f
这个选项,我们还可以使用pstree
来完全查看这个进程树。
(base) root@qi:~/Orion-Orion# pstree
sh─┬─bash
└─sshd─┬─sshd───bash─┬─sh───node─┬─node───12*[{node}]
│ │ ├─node─┬─node───10*[{node}]
│ │ │ ├─node───11*[{node}]
│ │ │ ├─python───{python}
│ │ │ └─11*[{node}]
│ │ ├─node───11*[{node}]
│ │ ├─node─┬─bash───pstree
│ │ │ └─11*[{node}]
│ │ └─10*[{node}]
│ └─sleep
└─2*[sshd───bash───sleep]
除此之外,我们必须要知道的是僵尸(zombie) 进程是什么?通常,造成僵尸进程的原因在于该进程应该已经执行完毕,或是应该要终止了,但该进程的父进程却无法完整地将该进程结束掉,而造成该进程一直存在内存中。如果你发现在某个进程的CMD
/COMMAND
后面接上了defunct
时,就代表该进程是僵尸进程,例如:
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>
系统不稳定的时候就容易造成所谓的僵尸进程,可能是因为程序写得不好,或是用户的操作习惯不良等所造成的。如果你发现系统中有很多僵尸进程时,记得要找出该进程的父进程,然后好好做个追踪,好好进行主机的环境优化,看看有什么地方需要改善,而不是直接将它kill掉。不然万一它一直产生就麻烦了。
事实上,通常僵尸进程都已经无法管理,而直接交给 systemd
这个进程来负责,偏偏systemd
是系统第一个执行的进程,它是所有进程的父进程。我们是无法杀掉该进程的(杀掉它,系统就死掉了),所以如果产生僵尸进程,而系统过了一阵子还没有办法通过内核非经常性的特殊处理来将该进程删除时,那你只好通过reboot
的方式来将该进程kill掉。
systemd
是目前Linux系统上主要的系统守护进程管理工具,由于init
一方面对于进程的管理是串行化的,容易出现阻塞情况,另一方面init
也仅仅是执行启动脚本,并不能对服务本身进行更多的管理。所以最新系统(RedHat7,CentOS7,Ubuntu15…)大