歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

殺不掉的僵屍(zombie)進程

殺不掉的僵屍(zombie)進程   Linux的進程,有以下幾種狀態(摘自本文): State Description D Uninterruptible sleep (usually IO) R Running or runnable (on run queue) S Interruptible sleep (waiting for an event to complete) T Stopped, either by a job control signal or because it is being traced. W Paging (not valid since the 2.6.xx kernel) X Dead (should never be seen) Z Defunct ("zombie") process, terminated but not reaped by its parent.   當一個進程處於Z狀態,我們稱之為zombie進程,如下所示: #top -b -p 56249   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           56249 ats       20   0     0    0    0 Z  0.0  0.0   5914:36 [ET_NET 0] <defunct>   正常情況下,處於zombie狀態的進程,會很快地被它的父進程回收,以致於我們根本不會注意到zombie進程的存在。可在實踐過程中,卻有一些無法使用kill -9命令殺掉的zombie進程,這常常令我們束手無策。   如果某個進程一直處於zombie狀態,可能會帶來一些嚴重的問題,例如,假設這個進程沒有正確地close掉socket,就會導致這些socket處於close_wait狀態,這些socket將會占用系統的ip/port資源,將導致其他程序無法創建特定socket。   當出現「殺不掉」的zombie進程,我們常常歸咎於kernel的bug,不了了之,但其實還有一種情況常常被忽略。讓我們看看上面的這個zombie進程內部,是否還有其他線程(使用top命令的-H參數): #top -b -H -p 56249  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                          56249 ats       20   0     0    0    0 Z  0.0  0.0 253:54.05 [ET_NET 0] <defunct>                                                                             56337 ats       20   0     0    0    0 D  0.0  0.0  38:53.67 [ET_AIO 0]                                                                                       56338 ats       20   0     0    0    0 D  0.0  0.0  38:48.24 [ET_AIO 1]                                                                                                                                                                        由上可見,雖然[ET_NET 0](pid=56249)進程處於zombie狀態,但它其實是一個多線程的程序,該程序中的其他線程,如[ET_AIO 0](pid=56337)等,處於D(Uninterruptible sleep)狀態,因為D狀態的進程(在Linux中,線程只是特殊的進程)無法被中斷,因此kill -9無法殺掉D狀態的進程。也正因為這些D狀態的進程的存在,導致父進程無法順利的回收它們。   通常,我們還需要分析處於D狀態的進程卡在了哪裡。可通過/proc文件系統查看D狀態進程的調用棧: #cat /proc/56337/stack [<ffffffff811b372e>] __blockdev_direct_IO_newtrunc+0x6fe/0xb90 [<ffffffff811b3c1e>] __blockdev_direct_IO+0x5e/0xd0 [<ffffffff811b1317>] blkdev_direct_IO+0x57/0x60 [<ffffffff81113543>] generic_file_aio_read+0x793/0x870 [<ffffffff81177c3a>] do_sync_read+0xfa/0x140 [<ffffffff81178635>] vfs_read+0xb5/0x1a0 [<ffffffff81178962>] sys_pread64+0x82/0xa0 [<ffffffff8100b0f2>] system_call_fastpath+0x16/0x1b [<ffffffffffffffff>] 0xffffffffffffffff   由上可見,該進程卡在了磁盤的read操作中,很可能是磁盤壞了。  
Copyright © Linux教程網 All Rights Reserved