關於正確避免殭屍進程(總結學習)

當子進程掛掉時,會給父進程發送一個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信號產生,也可以被處理!!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章