zombie不佔用記憶體也不佔用CPU,表面上我們可以不用在乎它們的存在,然而事實上UNIX系統限制了某一時刻能同時存在的進程的最大數目。如果程式不及時清理系統中的zombie,最終會導致進程數過多,當再次需要產生新進程時就會出錯。
鑒於上邊的原因,我們需要在子進程調用exit後在父進成中調用wait或waipid
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int &statloc);
pid_t waitpid(pid_t pid,int *statloc, int options);
Both return:process ID if OK,-1 on error
它們被父進程調用以擷取子進程結束資訊、清除zombie。當父進成調用這兩個函數時
a 阻塞(如果它的子進程還在運行)
b 立即返回子進程結束資訊(如果一個子進程已經結束並等待父進程擷取資訊)
c 返回錯誤(如果不存在子進程)
兩個函數的不同在於wait會令調用者阻塞直至某個子進程終止而waitpid則可以通過設定一個選項來設定為非阻塞,另外waitpid並不是等待第一個結束的進程而是等待參數中pid指定的進程。
兩個函數中的變數statloc是一個指向int型資料的指標。如果此變數不是NULL,則結束的進程的termination status會被儲存在statiloc所指向的記憶體的地區;如果我們不關心termination status,則可以把statloc置為NULL。
傳統的實現中這兩個函數返回的整數中特定的位元位被賦予了特定的含義。POSIX.1指定了一些包含在標頭檔<sys/wait.h> 宏來查看這些termination status
Macro Description
WIFEXITED(status) 如果status是由一個正常結束的進程產生的則值為真,此時我們可以繼續使用宏WEXITSTATUS(status)來擷取exit或_exit的參數
WIFSIGNALED(status) 如果status是由一個異常結束(接受到一個訊號)的進程產生的則值為真,此時使用宏WTERMSIG(status)來擷取訊號數。
WIFSTOPPED(status) 如果status是由一個接受到訊號目前終止的進程產生的則值為真,此時可以繼續調用宏WSTOPSIG(status)來查看是哪個訊號導致進程終止。