我們很多人對kill -9 非常熟悉,在工作中也經常用到。特別是你去重啟服務的時候。但是所有的服務都能用kill -9來處理嗎?kill -9能殺掉所有的進程嗎?
首先我們來了解一下 kill -n 中的n到底是什么東西。
kill
從help中可以清晰的看到 -n 指的是 信號編號,那問題來了,什么是“信號編號”?
kill -l(查看Linux/Unix的信號變量)
下面先說一下SIGKILL(kill -9)和SIGTERM(kill -15)
kill -9、kill -15
kill -9 PID 是操作系統從內核級別強制殺死一個進程.
kill -15 PID 可以理解為操作系統發送一個通知告訴應用主動關閉.
SIGNTERM(15) 的效果是正常退出進程,退出前可以被阻塞或回調處理。並且它是Linux缺省的程序中斷信號。
大部分程序接收到SIGTERM信號后,會先釋放自己的資源,然后再停止。但是也有程序可以在接受到信號量后,做一些其他的事情,並且這些事情是可以配置的。如果程序正在等待IO,可能就不會立馬做出響應。也就是說,SIGTERM多半是會被阻塞的、忽略。
但是kill -9 pid也不是所有的程序都會乖乖聽話,總有那些狀態下的程序無法立刻響應。
kill -9殺不掉的怎么辦
用ps和grep命令尋找僵屍進
ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'
命令注解:
-
-A 參數列出所有進程
-
-o 自定義輸出字段 我們設定顯示字段為 stat(狀態), ppid(進程父id), pid(進程id),cmd(命令)這四個參數 因為狀態為 z或者Z的進程為僵屍進程。
所以我們使用grep抓取stat狀態為zZ進程,運行結果參考如下:
Z 12334 12339 /path/cmd
這時,我們可以使用 kill -HUP 12339來殺掉這個僵屍進程
運行后,可以再次運行
ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'
來確認是否已經將僵屍進程殺死 如果kill 子進程無效,可以嘗試kill 其父進程來解決問題,例如上面例子父進程pid是 12334,那么我們就運行
kill -HUP 12334
來解決問題
一般可以用top命令發現動態進程表
其中zombie是僵屍進程
附錄:
linux signals