在子进程结束后产生了僵死进程,用了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) 提醒,抱歉,我可能讲的不是很清楚