linux 性能自我学习 ———— 不可中断进程和僵尸进程 [四]
前言
简单介绍一下不可中断进程和僵尸进程。
正文
先来看下进程的状态:
那么这一列的状态是什么呢?
R 是Running 或 Runnable 的缩写, 表示进程在cpu 的就绪队列中,正在运行或者正在等待运行。
D 是disk sleep 的缩写,也就是不可中断睡眠,一般表示进程正在跟硬件交互,并且交互过程不允许其他进程或者中断打断。
Z 是Zombie 的缩写,表示僵尸进程,表示进程已经介绍了,但是父进程还没有回收它的资源
S 是interruptible sleep 缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时, 他会被唤醒并进入R状态
I 是 idle的缩写, 也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致不可中断进程用D 表示,但是某些内核线程来说,他们可能实际并没有任何负载,用idle 就是为了区分。
D 状态的进程会导致平均负载升高,i 状态的进程不会。
还有两种状态,一种是T 状态,另外一种是X状态。
X 是状态为死亡,一般看不到。
另外一种是T 状态,表示是stopped 或者 traced 状态。
比如我们进程调试就是T状态,发送一个信号sigstop,然后就会停止。再发送sigcont 信号,这个时候就会继续运行。
该篇的主题是不可中断进程和僵尸进程。
前面结束了,不可中断进程,一般是在进行系统调用。
僵尸进程是怎么样的呢? 僵尸进程在多进程中可能遇到。
正常情况下,当用给进程创建了子进程后,它应该通过系统调用wait() 或者 waitpid() 等待子进程结束,回收子进程资源。
而子进程结束时候,会向父进程发送sigchld信号,所以父进程还可以注册sigchld 信号的畜栏里函数,异步回收资源。
如果父进程没有那么做,或者子进程执行太快。父进程还没来得及处理子进程状态,那么子进程就已经提前推出,那么这个时候子进程就会变成僵尸进程。
通常,僵尸进程持续时间很短,如果父进程一直没有处理子进程的终止,那么就会一直保持运行状态,这个时候就会占用pid 进程号,导致新的进程不能创建。
实验
docker run --privileged --name=app -itd feisky/app:iowait
top 一下:
僵尸进程特别多。
然后我们还发现了,Ss+ 和D+
这个+ 是什么意思呢?
有两个概念。
进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员
会话指共享一个控制终端的一个或者多个进程组。
那么这个时候,我们如何来分析呢?
yum install dstat
当iowait 升高时候,read 会很大,说明iowait 升高跟磁盘的读请求相关,可能是磁盘读导致的。
那么可以使用top 命令,观察d状态的进程。
然后通过pidstat
pidstat -d -p 4344 1 3
发现其并不高。
那么直接用pidstat 查看全部的:
pdistat -d 1 20
发现的确是app导致的。
然后就可以用strace 追踪代码了。
strace -p 6082
这种情况如果是root 用户查看不了的话,那么可能这个进程不存在或者已经Z状态了。
那么这个时候可以使用perf来搞定。
这个时候你就的确发现其在系统读取了。
那么僵尸进程怎么解决呢?
前面已经发现了僵尸进程了。
那么可以找到其父进程:
pstree -aps 3084
可以看到程序还是app进程了。
然后就可以去检查代码部分了。
结
下一节linux 软中断。