當子進程掛掉時,會給父進程發送一個SIGCHLD信號,而默認SIGCHLD信號是被忽略的。
我們可以在父進程裏設置一個SIGCHLD信號處理函數,在處理函數裏調用wait()函數,去爲子進程收屍。
void handler(int num)
{
wait();
}
但是這是有問題的。那就是有多個進程到達的情況:
假設有三個信號同時到達,第一個信號會觸發信號的處理函數,其他兩個信號會導致unix系統阻塞,但是並不會被緩存。
從而第二個信號被阻塞,而第三個信號被丟失了。如果其他子進程也退出了,那麼他們的信號也會被丟失!
信號處理函數只調用wait一次,所以每丟失一個信號,就意味着有了一個殭屍進程。解決方法是在處理函數中調用
足夠多次數的wait()去爲子進程收屍!
waitpid()函數就可以解決此問題!
void handler(int num)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
waitpid提供了wait函數的超集功能。第一個參數表示他所要等待的進程的進程號。值-1表示等待所有的子進程。第二個是一個指向整型的指針,用來獲取狀態
不需要的話,就賦值爲NULL,WNOHONG參數告訴waitpid如果沒有了殭屍進程則不必等待。
函數內的循環,將會持續到所有的殭屍進程被回收爲止,就算有再多的SIGCHLD信號產生,也可以被處理!!