暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

杀不死的进程

生有可恋 2023-03-31
526

最近遇到一个杀不死的进程,执行 kill -9 没有任何反应,进程卡在那儿处于不死不休的状态。

一般遇到进程卡死,执行 strace -p pid 可以观察进程的 API 调用过程来确定进程卡在哪一步。但当前这个进程处于假死状态,在 proc/pid 下查看进程状态为:

    cat /proc/44607/status
    Name: python
    State: D (disk sleep)
    Tgid: 44607
    Ngid: 0
    Pid: 44607
    PPid: 1
    TracerPid: 112702
    Uid: 0 0 0 0
    Gid: 0 0 0 0
    FDSize: 256
    Groups: 0
    NStgid: 44607
    NSpid: 44607
    NSpgid: 44607
    NSsid: 39779
    VmPeak: 29336 kB
    VmSize: 29336 kB
    VmLck: 0 kB
    VmPin: 0 kB
    VmHWM: 8692 kB
    VmRSS: 3212 kB
    VmData: 3396 kB
    VmStk: 132 kB
    VmExe: 2268 kB
    VmLib: 2788 kB
    VmPTE: 72 kB
    VmPMD: 12 kB
    VmSwap: 3664 kB
    HugetlbPages: 0 kB
    Threads: 1
    SigQ: 8/515089
    SigPnd: 0000000000000100
    ShdPnd: 0000000000004103
    SigBlk: 0000000000000000
    SigIgn: 0000000001001000
    SigCgt: 0000000180000002
    CapInh: 0000000000000000
    CapPrm: 0000003fffffffff
    CapEff: 0000003fffffffff
    CapBnd: 0000003fffffffff
    CapAmb: 0000000000000000
    Seccomp: 0
    Speculation_Store_Bypass: thread vulnerable
    Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff
    Cpus_allowed_list: 0-191
    Mems_allowed: 00000000,0000000f
    Mems_allowed_list: 0-3
    voluntary_ctxt_switches: 39715
    nonvoluntary_ctxt_switches: 1489

    之前通过 kill 杀掉了该进程的父进程,所以当前进程的父进程由1号进程继承。通过 strace 查看进程时,strace 也卡住了。

      $ ps -eaf| grep -v grep| grep 44607
      root 44607 1 0 329 ? /anaconda3/bin/python tmp/sum.py .
      root 112702  1  0 329 ?  strace -p 44607

      在 proc 文件系统中查看到的出问题的进程的状态为 D,网上的消息说是进程正在等待磁盘IO,并且进入到了内核态。

        State:  D (disk sleep)

        内核态的进程没法在用户态杀掉,只能等待进程自己从内核态出来。因为这个程序是在读取 NFS 文件时卡死的,所以八成与 NFS 有关。并且 NFS 挂载的磁盘当前负载较高,但 NFS 磁盘并没有卡死仍然可以读写。

        于是决定停掉 NFS 磁盘上的其它读写任务,看卡死的进程能否恢复。当停掉其它任务后,处于 disk sleep 状态的进程并没有从等待中恢复过来。查阅其他人的处理办法,只有一种选择就是重启服务器。但这个办法肯定不是可行的,毕竟这只是一个常规任务。

        除了这种状态为 D (disk sleep) 的进程不好杀,处于 Z 状态的进程也不好杀。

          $ ps -eaf| grep 186225
          $ root 186225 1 0 19:45 rsync -r --size-only pacs2/pacs/images/20201002_20/ pacs1/images/20201002_20
          $ root 186235 186225 0 19:45 [rsync] <defunct>


          $ cat /proc/186235/status
          Name: rsync
          State: Z (zombie)
          Tgid: 186235
          Ngid: 0
          Pid: 186235
          PPid: 186225


          $ cat /proc/186225/status
          Name: rsync
          State: D (disk sleep)

          本来处理僵尸进程,同时杀掉僵尸进程和它的父进程,一般是可以杀掉的。这里出现了一种情况就是它的父进程的状态也是 D (disk sleep),这就导致了僵尸进程杀不掉了。

          高并发的读写 NFS 文件系统很容易出现这种资源锁,一旦出现就只能从存储端断开客户端,不能因为进程杀不掉就重启系统。

          参考

            https://community.pivotal.io/s/article/Dealing-with-Processes-in-State-D---Uninterruptible-Sleep-Usually-IO?language=en_US
            https://stakoverflow.com/questions/1475683/linux-process-states
            https://unix.stackexchange.com/questions/407321/is-there-any-way-to-kill-or-end-a-process-in-disk-sleep
            https://stackoverflow.com/questions/223644/what-is-an-uninterruptible-process
            https://blog.csdn.net/davion_zhang/article/details/48268319
            https://blog.csdn.net/A___LEi/article/details/127661470?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-127661470-blog-48268319.235^v27^pc_relevant_t0_download&spm=1001.2101.3001.4242.1&utm_relevant_index=3
            https://zhuanlan.zhihu.com/p/92381918

            全文完。

            如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。

            文章转载自生有可恋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论