孤兒進(jìn)程
孤兒進(jìn)程: 父進(jìn)程先于子進(jìn)程結(jié)束,則子進(jìn)程成為孤兒進(jìn)程,子進(jìn)程的父進(jìn)程成為init進(jìn)程,稱為init進(jìn)程領(lǐng)養(yǎng)孤兒進(jìn)程。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0) {
while (1) {
printf("I am child, my parent pid = %d\n", getppid());
sleep(1);
}
} else if (pid > 0) {
printf("I am parent, my pid is = %d\n", getpid());
sleep(9);
printf("------------parent going to die------------\n");
} else {
perror("fork");
return 1;
}
return 0;
}
僵尸進(jìn)程
僵尸進(jìn)程: 進(jìn)程終止,父進(jìn)程尚未回收,子進(jìn)程殘留資源(PCB)存放于內(nèi)核中,變成僵尸(Zombie)進(jìn)程。
特別注意,僵尸進(jìn)程是不能使用kill命令清除掉的。因?yàn)閗ill命令只是用來終止進(jìn)程的,而僵尸進(jìn)程已經(jīng)終止。
wait函數(shù)
一個(gè)進(jìn)程在終止時(shí)會(huì)關(guān)閉所有文件描述符,釋放在用戶空間分配的內(nèi)存,但它的PCB還保留著,內(nèi)核在其中保存了一些信息:如果是正常終止則保存著退出狀態(tài),如果是異常終止則保存著導(dǎo)致該進(jìn)程終止的信號(hào)是哪個(gè)。這個(gè)進(jìn)程的父進(jìn)程可以調(diào)用wait或waitpid獲取這些信息,然后徹底清除掉這個(gè)進(jìn)程。我們知道一個(gè)進(jìn)程的退出狀態(tài)可以在Shell中用特殊變量$?查看,因?yàn)镾hell是它的父進(jìn)程,當(dāng)它終止時(shí)Shell調(diào)用wait或waitpid得到它的退出狀態(tài)同時(shí)徹底清除掉這個(gè)進(jìn)程。
父進(jìn)程調(diào)用wait函數(shù)可以回收子進(jìn)程終止信息。該函數(shù)有三個(gè)功能:
- 阻塞等待子進(jìn)程退出
- 回收子進(jìn)程殘留資源
- 獲取子進(jìn)程結(jié)束狀態(tài)(退出原因)。
pid_t wait(int *status);
成功:清理掉的子進(jìn)程ID;失敗:-1 (沒有子進(jìn)程)
當(dāng)進(jìn)程終止時(shí),操作系統(tǒng)的隱式回收機(jī)制會(huì):1.關(guān)閉所有文件描述符 2. 釋放用戶空間分配的內(nèi)存。內(nèi)核的PCB仍存在。其中保存該進(jìn)程的退出狀態(tài)。(正常終止→退出值;異常終止→終止信號(hào))
可使用wait函數(shù)傳出參數(shù)status來保存進(jìn)程的退出狀態(tài)。借助宏函數(shù)來進(jìn)一步判斷進(jìn)程終止的具體原因。宏函數(shù)可分為如下三組:
- WIFEXITED(status) 為非0→ 進(jìn)程正常結(jié)束
WEXITSTATUS(status) 如上宏為真,使用此宏 → 獲取進(jìn)程退出狀態(tài) (exit的參數(shù)) - WIFSIGNALED(status) 為非0 → 進(jìn)程異常終止
WTERMSIG(status) 如上宏為真,使用此宏 → 取得使進(jìn)程終止的那個(gè)信號(hào)的編號(hào)。 - WIFSTOPPED(status) 為非0 → 進(jìn)程處于暫停狀態(tài)
WSTOPSIG(status) 如上宏為真,使用此宏 → 取得使進(jìn)程暫停的那個(gè)信號(hào)的編號(hào)。
WIFCONTINUED(status) 為真 → 進(jìn)程暫停后已經(jīng)繼續(xù)運(yùn)行
waitpid函數(shù)
作用同wait,但可指定pid進(jìn)程清理,可以不阻塞。
pid_t waitpid(pid_t pid, int *status, in options);
成功:返回清理掉的子進(jìn)程ID;失?。?1(無子進(jìn)程)
特殊參數(shù)和返回情況:
參數(shù)pid:
>0 回收指定ID的子進(jìn)程
-1 回收任意子進(jìn)程(相當(dāng)于wait)
0 回收和當(dāng)前調(diào)用waitpid一個(gè)組的所有子進(jìn)程
< -1 回收指定進(jìn)程組內(nèi)的任意子進(jìn)程
返回0:參3為WNOHANG,且子進(jìn)程正在運(yùn)行。
注意:一次wait或waitpid調(diào)用只能清理一個(gè)子進(jìn)程,清理多個(gè)子進(jìn)程應(yīng)使用循環(huán)。