Top
«

什么叫进程被 D 了

阿布大人 发布于 阅读:98 私有分类


来源丨经授权转自 闪客公众号

作者丨闪客

小宇:闪客闪客,我在公司排查问题的时候,听到有人说某个进程被 D 了,听起来像是骂人一样,这到底是啥意思啊?

闪客:哈哈,这可不是骂人。不过这句话稍微有点歧义,有可能指进程被杀死了,但这么说会有点傻缺,还不如直接说进程被杀了。
小宇:那还有什么意思呢?
闪客:更有价值的意思是想表达,这个进程持续处于了 D 状态,这么说一看就是个老运维了。
小宇:这我更迷糊了,这是啥意思呢?
闪客:这里的 “D” 就表示一种进程状态,代表“不可中断的睡眠状态”,一般处在这种状态下的进程,比较随意的叫法就是进程被 D 了、发现了 D 进程等。

小宇:啥?睡眠还能不可断?它睡得多死?

闪客:哈哈,是的,确实可以理解为“死睡”。简单来说,进程在访问某些资源,比如硬盘或者网络 IO 的时候,如果这些操作被阻塞了,它就会进入“D”状态。

小宇:哦,那为啥不直接叫“阻塞”呢?非得搞个“D”这么神秘。
闪客:因为“D”来源于英文的“Disk Sleep”,最初是用来描述等待磁盘 IO 的状态。后来,这个定义扩展到所有不可中断的阻塞状态,就不局限于磁盘了。
小宇:原来如此,诶那进入这种状态的进程会怎么样呢?
闪客:字面意思的,就是会不可中断,最常见的就是给这个进程发一个 SIGKILL 信号,这个进程不会响应,表现起来就是这个进程是无法被杀掉或者打断的,只能等到它的资源请求完成。
小宇:那我怎么判断进程是不是 D 状态?

闪客:这个简单,用 top 或者 ps 命令就行了。比如 ps aux 的输出里,你会看到有些进程的 STAT 列是“D”,这就是它进入不可中断睡眠状态的标志。扩展下,除了这个状态之外其他的进程状态可以在内核源码中找到。

image.png


小宇:明白了,但为啥进程会卡在这个状态上?它不动不响的,是不是就有问题了?

闪客:没错,正常的 D 状态是短暂的,比如一个程序在读写文件时可能会瞬间进入 D 状态,所以 ps 查看进程的时候一般很难抓到有 D 进程的画面。
小宇:但是呢?
闪客:哈哈你咋学会抢答了。但如果一个进程长时间处于 D 状态,通常意味着它在等待的资源出现了问题,比如硬盘故障、网络断开或者锁被其他进程持有。

小宇:哦,这么说的话,这种问题有可能是硬件的,也有可能是软件的对吧?

闪客:正解!比如有一次我遇到的情况是数据库进程死死地 D 在那儿,检查后发现是存储服务器出了问题。还有一次是有个进程执行 sync 系统调用同步写盘,但磁盘故障了一直写不进去,也是一直 D 在了那里。

小宇:听起来解决起来应该挺麻烦吧?

闪客:是的,尤其是 D 状态的进程是不能被 kill 掉的,因为它们在等资源,这个等待过程完全由内核控制。你只能从根源上解决问题,比如排查硬盘、网络或者锁的情况,找到卡住的地方。解决不了就只能重启了。

小宇:那有没有什么工具能帮我分析这种问题?

闪客:当然有啦!比如 dstat 可以实时监控 IO 和 CPU 的状态,iotop 可以帮你看具体哪个进程占用了最多的 IO。用 strace 或者 lsof 查看进程当前在干啥(但你进程啥都不响应了其实也没辙)。实在不行还可以直接看内核日志,用 dmesg 或者 journalctl 找线索。

小宇:这么一说还真挺复杂的啊。

闪客:对啊,所以当你听到有人说进程 D 了,不要慌,先查查它在干啥。如果是硬盘或者网络问题,就找运维大哥帮忙;如果解决不了,就说只能重启就好了,这是正确的解法,只不过容易被人误解为菜鸡。

小宇:你这么一讲,我突然感觉进程被 D 是一种不幸的宿命啊。

闪客:对,就像陷入了黑洞一样,死活没办法,只能重启。话说,今天技术聊得够多啦,咱一块吃个饭放松放松脑子吧。

小宇:不了,我现在脑子有点 D 了,打算回家睡觉去咯,下次吧。
闪客:哦~