殭屍進程

在類UNIX系統中 ， 殭屍進程是指完成執行 （ 通過exit系統調用 ， 或運行時發生致命錯誤或收到終止信號所致 ） ， 但在操作系統的進程表中仍然存在其進程控制塊 ， 處於 " " 的進程 。 這發生於子進程需要保留表項以允許其父進程讀取子進程的退出狀態 ： 一旦退出態通過wait系統調用讀取 ， 殭屍進程條目就從進程表中刪除 ， 稱之爲 " 回收 " （ reaped ） 。 正常情況下 ， 進程直接被其父進程wait並由系統回收 。 進程長時間保持殭屍狀態一般是錯誤的並導致資源泄漏 。 英文術語zombie process源自喪屍 — — 不死之人 ， 隱喻子進程已死但仍然沒有被回收 。 與正常進程不同 ， kill命令對殭屍進程無效 。 孤兒進程不同於殭屍進程 ， 其父進程已經死掉 ， 但孤兒進程仍能正常執行 ， 但並不會變爲殭屍進程 ， 因爲被init （ 進程ID號爲1 ） 收養並wait其退出 。 子進程死後 ， 系統會發送SIGCHLD信號給父進程 ， 父進程對其默認處理是忽略 。 如果想響應這個消息 ， 父進程通常在信號事件處理程序中 ， 使用wait系統調用來響應子進程的終止 。 殭屍進程被回收後 ， 其進程號與在進程表中的表項都可以被系統重用 。 但如果父進程沒有調用wait ， 殭屍進程將保留進程表中的表項 ， 導致了資源泄漏 。 某些情況下這反倒是期望的 ： 父進程創建了另外一個子進程 ， 並希望具有不同的進程號 。 如果父進程通過設置事件處理函數爲SIG_IGN顯式忽略SIGCHLD信號 ， 而不是隱式默認忽略該信號 ， 或者具有SA_NOCLDWAIT標誌 ， 所有子進程的退出狀態信息將被拋棄並且直接被系統回收 。 UNIX命令ps列出的進程的狀態 （ " STAT " ） 欄標示爲 " Z " 則爲殭屍進程 。 收割殭屍進程的方法是通過kill命令手工向其父進程發送SIGCHLD信號 。 如果其父進程仍然拒絕收割殭屍進程 ， 則終止父進程 ， 使得init進程收養殭屍進程 。 init進程週期執行wait系統調用收割其收養的所有殭屍進程 。 爲避免產生殭屍進程 ， 實際應用中一般採取的方式是 ： 將父進程中對SIGCHLD信號的處理函數設爲SIG_IGN （ 忽略信號 ） ； fork兩次並殺死一級子進程 ， 令二級子進程成爲孤兒進程而被init所 “ 收養 ” 、 清理 。