開源學村

如何殺死 Linux 中的殭屍進程

據傳說,魂去身存還能活動的肉體名叫殭屍,常常出沒於深山老林之中。然而在現代,伴隨著 C 語言和 Unix 系統的誕生,賽博殭屍開始活躍於每一台電腦中。或者說,在使用電腦的過程中,有那麼一些進程由於種種原因,變成了雖然已經被自我殺死但還仍然佔用著資源的殭屍進程。與此相對的還有已經失去父進程、無法被正常調用本應該死亡但還在運行的孤兒進程。關閉孤兒進程是比較簡單的一件事,但檢索和 kill 殭屍進程要困難許多。

如何理解進程

程序們被執行的時候,它們會叫出一系列進程作為小弟,去具體跑腿來實現功能。比如我們可以用 ps 命令來查看當前的所有進程。

當然,不僅是程序會創建新進程,進程也可以創建新進程,這種情況下就會產生類似樹形的結構,我們可以用 pstree 來查看進程樹的情況。

更大的進程樹會像這樣:

可以看到每個進程都在系統中有一個編號,即 pid。pid 1的進程就是系統引導中執行的第一個進程,也就是 init 進程。在新版本的 Linux 中通常叫做 systemd。

使用 kill 來殺死進程

kill 命令是 Linux 系統中的一把最鋒利的劍,你可以用它來終止 Linux 系統中所有指定的進程。而只刪除一個進程會比較危險,要小心它的家人依舊存活在你的系統中,通過佔用資源來報復你。可以嘗試 killall 指令,它會幫助你下「誅九族」的命令。

如果單獨殺掉父進程而子進程沒能自動結束,子進程就變成了孤兒進程,但只要通過 ps 命令搜索到它的 pid,依舊可以簡單的結束掉它們。

如何殺死殭屍進程

那麼殭屍進程又有什麼特殊的呢?因為它們已經死過一次了,所以不能再殺掉了。

如果一個子進程自然終止,它們都會變成臨時的殭屍進程,直到父進程通過代碼釋放掉它們本來所佔用的資源。但如果父進程這一步失敗或被忽略了,這個子進程就變成了真正的殭屍進程,雖然不在運行,但還是空占著資源。所以你普通地用 kill 命令來結束掉它們的時候,一般情況下是不起作用的。

那麼要怎麼殺掉它們呢?答案是結束掉它們的父進程。首先用 ps 指令來找到需要殺死的殭屍進程,然後用 pstree 指令尋找它們的父進程,結束掉父進程,就可以實現目標了。假設 pid 827 是我們要結束的殭屍進程,而 pid 749是它的父進程,我們可以

$ sudo kill -9 749 

來結束掉它們的生命。

結束掉父進程是一個很方便的做法,但要注意最極端的情況:父進程的 pid 是 1。這種時候殺掉父進程,它會自動重啟,變成不死的殭屍 🙁


參考資料:

How to kill a zombie process on Linux

對這篇文章感覺如何?

太棒了
6
不錯
0
愛死了
0
不太好
0
感覺很糟
0

You may also like

Leave a reply

您的郵箱地址不會被公開。 必填項已用 * 標註

此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

More in:開源學村

開源學村

SoCal Linux博覽會回歸20周年

現在已經是支持和推廣FOSS社區的第20個年頭了,SCaLE 20x - 南加州Linux博覽會將於2023年3月9日至12日在帕薩迪納會議中心舉行。 這個為期4天的年度活動彙集了充滿活力的開源用戶社 […]
開源學村

如何在Linux上殺死殭屍進程

消滅殭屍進程! 也稱為「defunct」或「dead」進程 - 簡單來說,殭屍進程是指已經結束,但仍存在於系統進程表中的進程。理想情況下,一旦進程完成其工作/執行,它應該從進程表中清除。但由於某些原因 […]
開源學村

2022年,從學習Rust開始

Rust作為一個新語言,已經連續五年(2016,2017,2018,2019,2020)在Stack Overflow開發者調查的「最受喜愛編程語言」。Rust是一個值得學習的編程語言,它對安全的專註,會幫助你許多。學習Rust 從這本小小的Rust Cheat Sheet出發,了解Rust語言的基本操作。
開源學村

使用 Linux 命令行解決Wordle 問題

你可以使用 Linux 的 grep 命令和 fgrep 命令來解決Wordle 問題(進行篩選排除),grep 命令使用正則表達式進行搜索,fgrep 命令也像 grep 一樣搜索文本,但不使用正則表達式,grep 和 fgrep 命令在掃描單詞列表時提供了極大的靈活性。