Linux 系統中的進程可能處于如下狀態中的一種:
D = 不可中斷的休眠
I = 空閑
R = 運行中
S = 休眠
T = 被調度信號終止
t = 被調試器終止
Z = 僵尸狀態
Interruptible Sleep,可中斷睡眠,在 ps 命令中顯示 S。處在這種睡眠狀態的進程是可以通過給它發送信號來喚醒的。
Uninterruptible Sleep,不可中斷睡眠,在 ps 命令中顯示 D。處在這種睡眠狀態的進程無法立即處理任何發送給它的信號,這也是無法用 kill 殺掉它的原因。
僵尸進程可以被操作系統pid 1進程回收,前提是僵尸進程父進程是pid 1的進程;
重啟或者殺死產生這些僵尸進程的父進程,問題就解決了;
Z狀態
- 檢查僵尸進程
top命令
當zombie前的數量不為0時,即系統內存在相應數量的僵尸進程。2. 查詢父進程ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]'3. 通過父進程殺死僵尸進程kill -HUP 僵尸進程父ID4. 一鍵殺死所有僵死進程
ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' | awk -F" " '{ print $2 }' | xargs kill -HUP
實際使用
殺父進程kill -HUP
ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]'
ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' | grep daemon_guard.sh | awk -F" " '{ print $2 }' | xargs kill -HUP殺子進程kill -9
ps -ef |grep wsssr |grep -v grep |awk '{print $2}'|xargs kill -9
當你使用 kill -HUP 發送掛起信號(SIGHUP)給一個進程時,這通常會導致該進程終止。如果這個被信號殺死的進程是一個父進程,并且它有子進程在運行,那么這些子進程將會變為孤兒進程,其父進程PID會自動變為1(即init進程)。這是操作系統內核自動處理的,確保即使父進程不再存在,子進程也能被妥善管理。
簡而言之,kill -HUP 信號本身并不直接導致子進程的父進程變為1,而是父進程因收到該信號而終止這一行為,間接導致了子進程成為孤兒并被init進程接管。
D狀態
D狀態,也稱為不可中斷的睡眠狀態(Uninterruptible Sleep),是指進程正在等待某個資源(如磁盤I/O、網絡I/O或其他硬件操作)而暫時無法被調度執行的狀態。在這個狀態下,進程不響應信號,包括SIGKILL在內的大多數信號都無法中斷它,直到它等待的事件完成。以下是D狀態進程產生的幾種常見場景及處理方法:
產生原因:
I/O等待:進程可能在等待磁盤讀寫、網絡數據包到達等I/O操作完成。
鎖等待:進程可能在等待某個鎖,比如在多進程訪問共享資源時。
硬件交互:與硬件交互的操作,如磁盤檢查、硬件設備通信,可能導致進程進入D狀態。
NFS問題:當使用網絡文件系統(NFS)時,如果NFS服務器不可達或響應緩慢,訪問NFS文件的進程可能會進入D狀態。
處理方法:
診斷I/O問題:檢查是否有磁盤滿、硬件故障或網絡延遲等問題,使用如iotop、dmesg等工具輔助診斷。
檢查NFS狀態:如果是NFS相關問題,確保NFS服務器正常運行,使用ping、nfsstat等命令檢查。
強制重新掛載文件系統:如果是因為文件系統掛載問題,嘗試卸載再重新掛載有問題的文件系統。
系統日志:查看系統日志(如/var/log/messages或journalctl)以獲取更多關于進程為何進入D狀態的信息。
內核參數調整:在極端情況下,可能需要調整內核參數,如磁盤緩存相關的設置。
重啟服務或系統:作為最后手段,如果上述方法無效,可以考慮重啟受影響的服務或整個系統,但這可能會導致未保存的數據丟失。
避免使用kill -9:由于D狀態的進程不響應信號,通常不建議使用kill -9,因為這可能留下資源未被正確清理。但在確認無其他選項時,可考慮使用。
在處理D狀態進程時,重要的是先理解進程為什么會進入這種狀態,針對性地解決問題的根本原因,而非直接嘗試終止進程。