當我們寫服務器程序時,需要考慮服務器通常會運行很長時間,所以必須要包括一個SIGCHLD處理程序,來回收僵死子進程的資源。
因爲當SIGCHLD處理程序執行時,SIGCHLD信號是阻塞的,而UNIX信號是不排隊的,所以SIGCHLD處理程序必須準備好回收多個僵死子進程的資源。
定義SIGCHLD處理程序:
void handler(int sig)
{
while (waitpid(-1,0,WNOHANG)>0)
echo();//process
return;
}
當有子進程終止時,父進程執行handler。假設在父進程執行handler的時候,有n個子進程終止(即有n個SIGCHLD信號被髮送),當n>1時,就會有SIGCHLD被丟棄。
進程 終止時的信號
pid1 sig1
pid2 sig2
pid3 sig3
.
.
例如,當父進程在響應sig1的時候,進程pid2和pid3終止,發送了信號sig2和sig3,那麼sig2被阻塞,sig3被丟棄。父進程在處理完sig1之後會對sig2做出響應。父進程對sig2的響應過程首先進入while循環,很明顯此時有兩個子進程終止,waitpid回收其中的一個(不確定是pid2還是pid3),然後調用echo(),再循環回收另一個。這樣就不會出現殭屍進程了!
注意理解waitpid函數不是信號驅動的!
參考資料:http://bbs.chinaunix.net/thread-828942-1-1.html