Linux 中殭屍程式詳解
導讀 | 本文我們將來討論一下什麼是殭屍程式,殭屍程式是怎麼產生的,如何殺死一個殭屍程式。 |
講到程式,我們要先了解一下另一個概念:程式。
程式說白了就是躺在電腦硬碟上的一個檔案而已(如同硬碟女神一樣),在被 CPU 執行之前,它啥也做不了。
當程式被執行之後,它執行的例項就稱為程式 。一個程式可以對應多個程式。
程式是系統的工作單元。系統由多個程式組成,其中有的是作業系統程式(執行系統程式碼),其他的是使用者程式(執行使用者程式碼)。所有這些程式都會併發執行,例如通過在單 CPU 上採用多路複用來實現。
你可以使用 ps 檢視 Linux 系統中的所有程式 。
$ ps -ax PID TTY STAT TIME COMMAND 1 ? Ss 0:01 /usr/lib/systemd/systemd rhgb --switched-root --sys 2 ? S 0:00 [kthreadd] 3 ? I< 0:00 [rcu_gp] 4 ? I< 0:00 [rcu_par_gp]
當一個程式呼叫 fork 函式生成另一個程式,原程式就稱為父程式,新生成的程式則稱為子程式。
Linux 系統中這樣父子程式非常多,我們可以使用 pstree 檢視系統上的程式「譜系」。
$ pstree -psn systemd(1)─┬─systemd-journal(952) ├─systemd-udevd(963) ├─systemd-oomd(1137) ├─systemd-resolve(1138) ├─systemd-userdbd(1139)─┬─systemd-userwor(12707) │ ├─systemd-userwor(12714) │ └─systemd-userwor(12715) ├─auditd(1140)───{auditd}(1141) ├─dbus-broker-lau(1164)───dbus-broker(1165) ├─avahi-daemon(1166)───avahi-daemon(1196) ├─bluetoothd(1167)
每個程式在系統中都被分配了一個編號。在這所有的程式中,有個非常特殊的程式,它的 ID 號是 1 。它是系統在引導過程中執行的第一個程式,PID 1 之後的每個後續程式都是它的後代。
前面提到過,在 Linux 環境中,我們是通過 fork 函式來建立子程式的。建立完畢之後,父子程式獨立執行,父程式無法預知子程式什麼時候結束。
通常情況下,子程式退出後,父程式會使用 wait 或 waitpid 函式進行回收子程式的資源,並獲得子程式的終止狀態。
但是,如果父程式先於子程式結束,則子程式成為孤兒程式。孤兒程式將被 init 程式(程式號為1)領養,並由 init 程式對孤兒程式完成狀態收集工作。
而如果子程式先於父程式退出,同時父程式太忙了,無瑕回收子程式的資源,子程式殘留資源(PCB)存放於核心中,變成殭屍(Zombie)程式,如下圖所示:
前面已經介紹了殭屍程式產生的原理,下面我們通過程式碼來模擬殭屍程式的產生。
#include #include #include #include int main(void) { pid_t pid; pid = fork(); if (pid == 0) { printf("I am child, my parent= %d, going to sleep 3s\n", getppid()); sleep(3); printf("-------------child die--------------\n"); } else if (pid > 0) { printf("I am parent, pid = %d, myson = %d, going to sleep 5s\n", getpid(), pid); sleep(5); system("ps -o pid,ppid,state,tty,command"); } else { perror("fork"); return 1; } return 0; }
在這個程式裡,父程式建立子程式之後,就休眠 5 秒鐘。而子程式只休眠 3 秒鐘就退出,在它退出之後,父程式還未甦醒,因此沒人給子程式「收屍」,所以它就變成了殭屍程式。
對於普通程式,我們可以通過使用 kill 命令來殺死它們。kill 命令它還有幾個兄弟,比如 pkill 和 killall ,雖然它們名稱裡都帶 kill 這樣殺氣騰騰的字眼,但它們實際上是被設計為向一個或多個程式傳送訊號。
在未指定的情況下,這幾個命令預設傳送的是 SIGTERM 訊號。
普通程式可以被 kill ,但殭屍程式是不行的。為什麼?因為殭屍程式本身就已經「死」過一次了!如果還可以再「死」,那「殭屍」這個名號就沒多大意義了。
殭屍程式其實已經就是退出的程式,因此無法再利用kill命令殺死殭屍程式。殭屍程式的罪魁禍首是父程式沒有回收它的資源,那我們可以想辦法它其它程式去回收殭屍程式的資源,這個程式就是 init 程式。
因此,我們可以直接殺死父程式,init 程式就會很善良地把那些殭屍程式領養過來,併合理的回收它們的資源,那些殭屍程式就得到了妥善的處理了。
例如,如果 PID 5878 是一個殭屍程式,它的父程式是 PID 4809,那麼要殺死殭屍程式 (5878),您可以結束父程式 (4809):
$ sudo kill -9 4809 #4809 is the parent, not the zombie
殺死父程式時要非常小心,如果一個程式的父程式就是 PID 1 ,並且你還殺死了它,那麼系統將直接重啟!
這將是一個更可怕的故事!
本文原創地址:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2842835/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux系統殭屍程式詳解Linux
- Linux中殭屍程式是什麼意思?怎麼檢視殭屍程式?Linux
- 檢視 Linux 殭屍程式Linux
- Linux殭屍程式處置Linux
- Linux 效能優化之 CPU 篇 ----- 殭屍程式Linux優化
- 殭屍程式,孤兒程式
- fork和殭屍程式
- 殭屍程式和孤兒程式
- Perl程式:殭屍程式和孤兒程式
- 子程式、孤兒程式,殭屍程式, init程式
- 物聯網教程Linux系統程式設計——特殊程式之殭屍程式Linux程式設計
- Linux上的殭屍跑得比Windows快LinuxWindows
- Go Exec 殭屍與孤兒程式Go
- PHP 多程式之孤兒和殭屍簡單講解PHP
- Linux 幹掉狀態為Z的殭屍程序Linux
- JaCoCo助您毀滅線上殭屍程式碼
- 什麼是殭屍程式以及如何處理
- 系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?
- 植物大戰殭屍 2.0中文版
- UNIXC002 程式資源的回收、孤兒程式和殭屍程式
- 孤兒程序和殭屍程序
- Unity 植物大戰殭屍(一)Unity
- 什麼是殭屍網路
- 案例:系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?
- 3.19實戰殭屍工廠1
- 3.20實戰殭屍工廠2
- Mirai殭屍網路重出江湖AI
- 《植物大戰殭屍》10歲了
- 植物大戰殭屍 雜交版
- 植物大戰殭屍-雜交版
- 【多程式】Linux中fork()函式詳解|多程式Linux函式
- 植物大戰殭屍win10開啟閃退怎麼解決_win10植物大戰殭屍開啟閃退解決步驟Win10
- Linux詳解 --- 程式管理Linux
- 帶你瞭解殭屍網路是怎樣組成的?
- 怎樣有效的治理殭屍網路?
- 揭秘Neutrino殭屍網路生成器
- RDP服務之GoldBrute殭屍網路Go
- 植物大戰殭屍1.2.0.1073漢化版