今天登陸到服務器上時,系統打印有6 zombie processes存在,因而用kill -9去清理掉這些殭屍進程,命令執行完後沒有錯誤,但是再次查找時,發現殭屍進程仍然存在,不知道怎麼清理了,上網找了一下,學習一下。 linux
在UNIX 系統中,一個進程結束了,可是他的父進程沒有等待(調用wait / waitpid)他, 那麼他將變成一個殭屍進程. 在fork()/execve()過程當中,假設子進程結束時父進程仍存在,而父進程fork()以前既沒安裝SIGCHLD信號處理函數調用 waitpid()等待子進程結束,又沒有顯式忽略該信號,則子進程成爲殭屍進程。
如何查看linux系統上的殭屍進程,如何統計有多少殭屍進程?
shell
#ps -ef | grep defunct或者
#ps aux | grep defunct
或者查找狀態爲Z的進程,Z就是表明zombie process,殭屍進程的意思。
另外使用top命令查看時有一欄爲S,若是狀態爲Z說明它就是殭屍進程。top命令中也統計了殭屍進程。
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie
服務器
top - 10:05:03 up 11 days, 1:17, 7 users, load average: 0.00, 0.01, 0.05 Tasks: 178 total, 1 running, 174 sleeping, 3 stopped, 0 zombie
通常殭屍進程很難直接kill掉,不過您能夠kill殭屍爸爸。父進程死後,殭屍進程成爲」孤兒進程」,過繼給1號進程init,init始終會負責清理殭屍進程.它產生的全部殭屍進程也跟着消失。
併發
# ps -e -o ppid,stat | grep Z | cut -d‘ ’ -f1 | xargs kill -9另外子進程死後,會發送SIGCHLD信號給父進程,父進程收到此信號後,執行waitpid()函數爲子進程收屍。就是基於這樣的原理:就算父進程沒有調用wait,內核也會向它發送SIGCHLD消息,而此時,儘管對它的默認處理是忽略,若是想響應這個消息,能夠設置一個處理函數。
處理SIGCHLD信號並非必須的。但對於某些進程,特別是服務器進程每每在請求到來時生成子進程處理請求。若是父進程不等待子進程結束,子進程將成爲殭屍進程(zombie)從而佔用系統資源。若是父進程等待子進程結束,將增長父進程的負擔,影響服務器進程的併發性能。在Linux下 能夠簡單地將 SIGCHLD信號的操做設爲SIG_IGN。
函數
signal(SIGCHLD,SIG_IGN);這樣,內核在子進程結束時不會產生殭屍進程。這一點與BSD4不一樣,BSD4下必須顯式等待子進程結束才能釋放殭屍進程。