孤兒進程與僵屍進程的區別
普通進程資源回收過程
正常情況下,子進程由父進程創建,父子進程是一個異步過程,子進程結束之后父進程一般會調用wait()或者waitpid()取得子進程的終止狀態,然后回收子進程的資源。
孤兒進程
孤兒進程: 父進程結束了,但是他的一個或者多個子進程還在運行,那么這些子進程就變成了孤兒進程(father died).子進程的資源由Init進程(進程號PID = 1)回收。
僵屍進程
僵屍進程:子進程退出了,但是父進程沒有調用wait() 或者waitpid() 去獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中,這種進程稱為僵屍進程。
僵屍進程的危害
系統所能使用的進程號是有限的,如果大量差生僵屍進程,將因為沒有可用的進程號,導致無法產生新的進程,這就是僵屍進程的危害。孤兒進程是沒有父進程,init 進程充當父進程,因此孤兒進程並沒有什么危害。
解決僵屍進程的方案
任何一個子進程(init除外)在exit()之后,並非馬上就消失掉,而是留下一個成為僵屍進程的數據結構,等待父進程去處理。如果父進程在子進程exit()之后,沒有及時處理,出現了僵屍進程,並可以用ps命令去查看,它的狀態是“Z”
- Kill -9 父進程的pid值 將僵屍進程轉換為孤兒進程然后由系統進行回收
- 父進程調用wait 或者waitpid 等待子進程結束,但是性能不會太好,因為一直有父進程處於等待的狀態下,沒有起到多進程的作用。
- 通過信號機制,子進程退出時向父進程發送SIGCHLD信號,父進程調用signal(SIGCHLD,sig_child)去處理SIGCHLD信號,在信號處理函數sig_child()中調用wait進行處理僵屍進程。什么時候得到子進程信號,什么時候進行信號處理,父進程可以繼續干其他活,不用去阻塞等待。
注意: 僵屍進程無法直接使用kill 殺死