在子進程結束后產生了僵死進程,用了signal(SIGCHLD,SIG_IGN)和signal(SIGCLD,SIG_IGN)都不行,兩個能一起用嗎?
你產生子進程時fork兩次,這樣由于第一次fork產生的子進程在fork之后就退出,所以第二次fork產生的子進程成為“孤兒“進程,init進程會接管它,成為它的父進程,而init進程肯定會處理了SIGCHLD信號,所以這樣也不會出現僵死進程。
在fork前加上信號處理函數:
signal(SIG_CHLD, Proc_CHLD);
void Proc_CHLD(int SIGNO)
{
int pid = -1;
int stat;
while(pid=waitpid(0, &stat, WHNONG);
}
1 樓95533(鼠標墊)
回復于 2002-11-11 09:40:38 得分 0
可以一起用,這兩句的意思是屏蔽SIGCHLD和SIGCLD信號。Top
2 樓ari(薛定鍔)回復于 2002-11-11 10:15:36 得分 0
fork 兩次即可解決Top
3 樓gongdath(gongdath)回復于 2002-11-11 12:39:28 得分 0
應該在父進程中調用wait或waitpid涵數.Top
4 樓1010101010(Number)回復于 2002-11-12 09:31:37 得分 0
最好是用waitpid,因可能有多個子進程,而unix的 信號是不排隊的Top
5 樓wang11912(天天練習)回復于 2002-11-26 12:01:20 得分 0
可是有的程序也沒有用wait,waitpid卻沒有產生僵死進程,真的不知道為什么?
Top
6 樓yanyanyan(西門吹鹽)回復于 2002-11-26 14:30:13 得分 10
只有長期運行而且要產生子進程的程序才需要用wait或waitpid。
僵死進程產生的原因:
子進程退出后(不管是否是正常退出),它在內存中會遺留部分信息成為一個僵死進程,同時內核會向其父進程發送SIGCHLD(或SIGCLD)信號。此時要分幾種情況:
1、父進程處理SIGCHLD信號,調用wait,僵死進程消失。這樣我們就看不到僵尸進程。
2、父進程忽略SIGCHLD信號,隨著子進程不斷產生、結束,僵死進程的數目不斷增加,導致影響系統速度及其他一些問題。
不需長期運行的程序,即使產生子進程也不會導致大量僵死進程存在。因為,父進程退出時,其產生的子進城成為“孤兒“進程,由init(1號進程)進程接管,init進程在子進程退出時會處理SIGCHLD信號,給子進程“收尸“。
推薦摟主看本書--《Advanced Programming in the UNIX Environment》(Richard Stevents著)。
Top
7 樓wang11912(天天練習)回復于 2002-11-26 17:25:20 得分 0
有的長期運行的程序只用了
signal(SIGCHLD,SIG_IGN);
都不會產生僵死進程,為什么加了
signal(SIGCLD,SIG_IGN);
都不管用,都在AIX下運行。
按照Advanced Programming in the UNIX Environment中的說法,如果用了
signal(SIGCHLD,SIG_IGN)就可避免僵死進程了
Top
8 樓wwwunix(木易)回復于 2002-11-26 17:46:40 得分 5
解決辦法:
在父進程中用wait()或waitpid()來接收終止的子進程。Top
9 樓yanyanyan(西門吹鹽)回復于 2002-11-27 10:50:16 得分 0
-----------------------------------------------------------------
按照Advanced Programming in the UNIX Environment中的說法,如果用了
signal(SIGCHLD,SIG_IGN)就可避免僵死進程了??????????????
-----------------------------------------------------------------
誰說的?
signal(SIGCHLD,SIG_IGN)是什么意思?--忽略SIGCHLD信號!!!!
在長期運行的程序忽略SIGCHLD信號只會產生很多僵死進程直到父進程結束。
只有在父進程中捕獲SIGCHLD信號,并在SIGCHLD信號處理函數中調用wait才能避免僵死進程的出現。
當然ari(男人阿日)說的辦法也行,就是在你產生子進程時fork兩次,這樣由于第一次fork產生的子進程在fork之后就退出,所以第二次fork產生的子進程成為“孤兒“進程,init進程會接管它,成為它的父進程,而init進程肯定會處理了SIGCHLD信號,所以這樣也不會出現僵死進程。
摟主的理解有點偏差,好好看看大家的貼子巴。《Advanced Programming in the UNIX Environment》上也說的很清楚。
Top
10 樓flyingcrean(flying鶴)回復于 2002-11-27 13:51:27 得分 0
在fork前加上信號處理函數:
signal(SIG_CHLD, Proc_CHLD);
void Proc_CHLD(int SIGNO)
{
int pid = -1;
int stat;
while(pid=waitpid(0, &stat, WHNONG);
}
Top
11 樓wang11912(天天練習)回復于 2002-11-27 15:20:10 得分 0
我已經改為用wait的方式了,解決了。
因為是別人的程序,本來不想改動,所以奇怪為什么原來沒有問題,現在卻導致經常要重新啟動,可能是操作系統哪個補丁沒打上。
謝謝大家。Top
12 樓bnwxf(有一種感覺叫從容)回復于 2002-11-28 20:46:29 得分 0
unix 網絡編程。
里面將了一個用循環寫的SIG_CLD的處理函數。
如果子進程很多,推薦用這一標準做法。Top
13 樓whoke(hy)回復于 2002-12-07 14:50:17 得分 5
to yanyanyan(西門吹鹽) ( ) 信譽:100 2002-11-27 10:50:00 得分:0
APUE上是這么說的,不過是指明了版本的.SVR4不會產生僵尸,而4.3+BSD必須wait waitpid 才能避免產生僵尸進程。
兩次fork要保證父進程在子進程退出前exit.Top
14 樓cwhh(hh)回復于 2002-12-28 17:56:59 得分 0
一般當一個進程終止后都會發送SIGCHLD信號給它的父進程,并由此變為僵死進程直到父進程接收了其狀態報告其資源才會被系統釋放;
處理方法有3種:
1. 當子進程終止時父進程接收SIGCHLD信號并調用waitpid()函數接收其狀態報告,最好用sigaction(),signal()不可靠;
2. 通過函數sigaction指明標志SA_NOCLDWAIT來指定信號SIGCHLD的動作,這使得內核在調用者的子進程終止時不創建僵死進程。
3. 二次fork調用;
Top
15 樓yanyanyan(西門吹鹽)回復于 2002-12-30 10:57:06 得分 0
謝謝 whoke(hy) 提醒,抱歉,我可能講的不是很清楚