1. 孤兒進程:父進程先於子進程結束,則子進程成為孤兒進程,子進程的父進程變為init進程 。
2. 僵屍進程:子進程終止了,父進程尚未回收子進程,子進程殘留資源(PCB)存放於內核中,子進程變成僵屍(Zombie)進程。
問:那為什么子進程要把PCB殘留在內核里呢?
答:因為子進程終止后,它會把終止信號等退出狀態(不管正常終止還是異常終止都對應一個信號)保存在內核的PCB里面,只有這個子進程的父親節調用wait或者waitpid獲取這些退出狀態,然后才會徹底清除掉這個子進程。如果父進程不調用wait或者waitpid,那么這個子進程就會成為僵屍進程。
問:什么方法可以清除掉一個僵屍進程。(附:kill命令清除不了僵屍進程的,因為kill命令只是用來終止進程的,而僵屍進程已經是終止的了)
答:kill確實是直接清除不掉僵屍進程,但是我們可以kill掉僵屍進程的父進程,這樣僵屍進程的父進程就變為init進程,init進程自然會調用wait或者waitpid清除這個僵屍進程。
3. wait函數
pid_t wait(int *status); //status傳出參數,存放子進程的退出狀態信息
附:父進程一旦調用該函數,就會阻塞等待,直到子進程退出
返回值:成功返回子進程id,失敗返回-1(無子進程) 。
status傳出參數保存着子進程的退出狀態,下面對其說明如下:
4. waitpid函數
pid_t waitpid(pid_t pid, int *status, int options);
功能:和wait一樣,但是這個函數清除指定的pid,可以不阻塞父進程
返回值:成功返回清除掉的進程pid,失敗返回-1 (無子進程) 。當options指定為WNOHANG時,返回0表示子進程正在運行。
下面對pid的不同取值情況的說明:
>0 表示回收指定ID的子進程
-1 表示回收任意子進程(相當於wait)
0 表示回收和當前調用waitpid一個組的所有子進程
<-1 表示回收指定進程組內的任意子進程,比如-6610表示回收進程組id為6610的任意子進程
附:一次wait或waitpid調用只能清理掉一個子進程,清理多個子進程應該使用循環調用多次 。