如何找到並殺掉 Linux 系統中的殭屍進程
在了解殭屍進程之前,讓我們來複習一下什麼是 Linux 進程。
簡而言之,進程 是一個程序的運行實例。它可能運行在前端(比如有交互的進程),也可能運行在後端(比如無交互或自動運行的進程)。它可能是一個父進程(運行期間創建了其他進程),也可能是一個子進程(由其他進程所創建)。
在 Linux 系統中,除 PID 為 0 的第一個 init
進程(或 systemd
)外,其餘進程都有父進程。進程也可以擁有自己的子進程。
不相信?可以試試在終端中使用 pstree
命令查看進程的樹型結構,你能看到系統各個進程的「家族樹」。
Linux系統里的殭屍進程是什麼?
子進程死亡後,它的父進程會接收到通知去執行一些清理操作,如釋放內存之類。然而,若父進程並未察覺到子進程死亡,子進程就會進入到「 殭屍 」狀態。從父進程角度看,子進程仍然存在,即使子進程實際上已經死亡。這就是「 殭屍進程 」(也被稱為「 已消失進程 」)是如何產生並存在於系統中的。
這裡有一個來自 Turnoff.us 的關於殭屍進程的非常有趣的看法:
你真的需要關心殭屍進程嗎?
重點要說的是,殭屍進程並沒有像它的名稱那樣看起來可怕。
但如果系統的內存已經所剩不多或者有太多的殭屍進程在吃掉內存,問題會變得糟糕。同樣,大部分 Linux 系統進程最大 PID 設置為 32768,如果過多殭屍進程導致其他重要任務沒有 PID 可用,你的系統會發生崩潰。
這是真實可能發生的,它有一定的概率,特別當存在一個編碼糟糕的程序開始大量產生殭屍進程的時候。
在這種情況下,找到並殺死殭屍進程是一個明智的做法。
如何找到殭屍進程
Linux 系統中的進程可能處於如下狀態中的一種:
D
= 不可中斷的休眠I
= 空閑R
= 運行中S
= 休眠T
= 被調度信號終止t
= 被調試器終止Z
= 殭屍狀態
那如何查看進程和它的當前狀態呢?一個簡單的方法是在終端中使用 top 命令。
正如你在上面截圖中看到的,截圖中共有 250 個任務(進程),其中 1 個處在 「 運行中 」 狀態,248 個進程處於 「 休眠 」 狀態,還有一個處於 「 殭屍 」 狀態。
現在問題進入下一步,如何殺死 「殭屍」 進程?
如何找到並殺死一個殭屍進程?殭屍進程能被殺死嗎?
殭屍進程已經死了,要如何才能殺死一個已經死亡的進程呢?
在殭屍電影中,你可以射擊殭屍的頭部或燒掉它們,但在這裡是行不通的。你可以一把火燒了系統來殺死殭屍進程,但這並不是一個可行的方案。
一些人建議發送 SIGCHLD
給父進程,但這個信號很可能會被忽略。還有一個方法是殺死父進程來殺死殭屍進程,這聽起來很野蠻,但它卻是唯一能確保殺死殭屍進程的方法。
首先,通過在終端中 使用 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]'
現在你得到了父進程 ID,使用命令行和得到的 ID 號 終於可以殺死進程了:
kill -9 <parent_process_ID>
再次運行 ps
命令或 top
命令,你可以驗證殭屍進程是否已經被殺死。
恭喜!現在你知道怎麼清理殭屍進程了。
via: https://itsfoss.com/kill-zombie-process-linux/
作者:Marco Carmona 選題:lujun9972 譯者:zengyi1001 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive