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傳出參數儲存着子程序的退出狀态,下面對其說明如下:
if (WIFEXITED(status)) { //IFEXITED非0,程序正常退出
printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) { //IFSIGNALED非0,程序被某個信号異常終止
printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) { //IFSTOPPED非0,程序收到某個信号而暫停
printf("stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) { //IFCONTINUED非0,程序從暫停狀态變為繼續運作狀态
printf("continued\n");
}
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調用隻能清理掉一個子程序,清理多個子程序應該使用循環調用多次 。