Linux 系統中,進程就是一個程序的運行實例。它可能運行在前端(比如有交互的進程),也可能運行在後端(比如無交互或自動運行的進程)。它可能是一個父進程(運行期間創建了其他進程),也可能是一個子進程(由其他進程所創建)。
在 Linux 系統中,除 PID 爲 0 的第一個 init
進程(或 systemd
)外,其餘進程都有父進程。進程也可以擁有自己的子進程。
你可以通過使用 pstree 命令來查看進程的樹型結構,你可以清晰的看到各個進程的“家族樹”。
什麼是殭屍進程
在 Linux 系統中,正常情況下,子進程死亡後其父進程會接收到通知進行一些例如釋放內存之類的清理操作。但是,如果父進程未收到通知察覺子進程死亡,那麼子進程就進入了“僵死”狀態。
這就是僵死進程產生的原因。
碰到殭屍進程怎麼辦?
殭屍進程並不可怕,少量的殭屍進程對系統影響並不大。但如果系統的內存已經所剩不多或者有太多的殭屍進程在耗掉內存,問題會變得糟糕。
同樣,大部分 Linux 系統進程最大 PID 設置爲 32768,如果過多殭屍進程導致其他重要任務沒有 PID 可用,那麼你的系統會發生崩潰。
特別當存在一個編碼糟糕的程序開始大量產生殭屍進程的時候,這種情況經常發生。在這種情況下,我們就需要找到並殺死殭屍進程。
如何查找殭屍進程
在linux系統中,進程有如下幾種狀態,它們隨時可能處於以上狀態中的一種:
D
= 不可中斷的休眠I
= 空閒R
= 運行中S
= 休眠T
= 被調度信號終止t
= 被調試器終止Z
= 殭屍狀態
我們可以在命令終端中通過top命令來查看系統進程和它的當前狀態。
命令如下:
top
如上面截圖中看到的,其中共有 250 個任務(進程),其中 1 個處在 “運行中running” 狀態,248 個進程處於 “休眠sleep” 狀態,還有一個處於 “殭屍zombie” 狀態。
現在問題進入下一步,如何殺死 “殭屍” 進程?
殺死殭屍進程
殭屍進程對系統來說就是已經死亡的進程,那麼如何殺掉一個已經死亡的進程呢?
方法很簡單,我們只需要通過如下ps命令就可以列舉殭屍進程,得到它們的進程 ID。
ps ux | awk '{if($8=="Z+") print}'
ps ux
命令輸出的第 8 列顯示了進程狀態。上述命令將會打印所有處在 Z+ 狀態(表示殭屍狀態)的進程。
確認了進程 ID 後,我們可以得到它的父進程 ID:
ps -o ppid= -p <child_id>
你也可以將上述兩個命令結合在一起,直接得到殭屍進程的 PID 及其父進程的 PID:
ps -A -ostat,pid,ppid | grep -e '[zZ]'
通過以上命令都可以找到殭屍進程,然後你就可以通過kill命令殺掉了。
kill -9 父進程號
或者通過如下命令查看殭屍進程:
ps -ef | grep defunct
該命令輸出結果上你可以直接看出其父進程ID,這時候你直接使用kill命令殺掉即可。
再次運行 ps
命令或 top
命令,你可以驗證殭屍進程是否已經被殺死。
寫在最後
通過本文你將認識 Linux 系統中的殭屍進程以及明白了其產生的主要原因。同時,你也能學會如何查找殭屍殭屍進程並殺掉殭屍進程。
當然你也可以自己別寫腳本設置成定時運行任務自動來替你做這些工作。