忽略SIGCHLD信号能避免僵尸进程吗?

jluliuchao 2009-09-11 04:33:35
主程序要一直运行,会经常调用另一个程序,运行久了之后就看到很多僵尸进程,在网上看到有人说忽略SIGCHLD信号能避免僵尸进程,因为忽略SIGCHLD后僵尸进程会交给init管理,也有人说忽略SIGCHLD只会让僵尸进程越来越多。
麻烦各位说说你们的看法
...全文
1791 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
asdfghjkl_wz 2010-05-12
  • 打赏
  • 举报
回复
同仁,怎么解决的啊?
jluliuchao 2009-09-12
  • 打赏
  • 举报
回复
问题已解决,非常感谢各位!
mymtom 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jluliuchao 的回复:]
为什么要在sig_chld加signal(SIGCHLD, &sig_chld);
我看很多文章里都没加,有什么原因吗?
[/Quote]
加上后,如果在进入信号处理函数和调用signal(SIGCHLD, &sig_chld);之间
又几个子进程结束,可能会留下几个zombie, 但是,一旦signal(SIGCHLD, &sig_chld);调用
结束,又有子进程结束的话,
while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
将会清除上次这些zombie. 这样就基本消除了zombie产生的可能性。

最好使用sigaction 代替signal, 可以完美的保证在支持(sigaction + waitpid)不会留下zombie.
实际上很多Unix系统上zombie是进程的必经阶段,是给父进程机会查看子进程的退出状态。
sigaction + waitpid 完全可以可靠的清除zombie,不要把自己的工作留给系统去做。
使用fork的服务器服务程序,会不断产生子进程,子进程完成任务后会退出,如果不清除zombie,
会缓慢消耗系统资源的。
mymtom 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jluliuchao 的回复:]
师兄说不用管这些僵尸进程,因为系统会回收的,是这样吗?
[/Quote]
当然不是,除非这些僵尸的父进程结束。
mymtom 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jluliuchao 的回复:]
为什么要在sig_chld加signal(SIGCHLD, &sig_chld);
我看很多文章里都没加,有什么原因吗?
[/Quote]
部分源自System V的Unix(比如AIX)的signal()函数保留了原始Unix的不可靠信号的语意:
信号被捕获后,信号处理自动被重置为SIG_DEF,就好像调用了signal(SIGCHLD, SIG_DEF)一样,
而且不会屏蔽正在处理的信号。
所以,需要在信号处理函数内的开始重新安装信号处理函数
当然这里也存在一个时间窗,在进入信号处理函数后,调用signal之前又收到信号的话,如果这个信号
的缺省行为是结束进程的话,进程可能会意外终止。
当然在这里,SIGCHLD的缺省行为不会终止进程,但是由于信号处理函数被重置,还会留下zombie,

POSIX 的sigaction就提供和可靠信号:
1. 从不重置信号处理为SIG_DEF, 除非特别设置。
2. 在信号处理函数执行期间,自动屏蔽正在处理的信号,除非特别设置。
superbtl 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jluliuchao 的回复:]
师兄说不用管这些僵尸进程,因为系统会回收的,是这样吗?
[/Quote]当父进程结束 这子进程就成了孤儿进程 INIT进程会领养 子进程结束就没了
这个只是在系统上有条记录,不占资源,等回收后连记录都没了。但是在有些调试状态会一直有
kill -9 PID可以杀掉 弄不好要有个记录 占用了一个进程ID而已,不碍事
jluliuchao 2009-09-11
  • 打赏
  • 举报
回复
师兄说不用管这些僵尸进程,因为系统会回收的,是这样吗?
jluliuchao 2009-09-11
  • 打赏
  • 举报
回复
为什么要在sig_chld加signal(SIGCHLD, &sig_chld);
我看很多文章里都没加,有什么原因吗?
mymtom 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jluliuchao 的回复:]
3. 通过sigaction系统调用指定信号SIGCHLD处理动作中的sa_flags为SA_NOCLDWAIT

用这种方法好像也不行啊,还是有僵尸进程.怎么办?
[/Quote]
这种方法,不是所有的操作系统都实现了。
前面的帖子有点问, 应该加一句:

void sig_chld(int signo)
{
pid_t pid;
int stat;

signal(SIGCHLD, &sig_chld);
while((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf("child %d terminated\n", pid);
}
return;
}

int main(void)
{
int rc;

rc = 0;
signal(SIGCHLD, &sig_chld);
return (rc);
}

mymtom 2009-09-11
  • 打赏
  • 举报
回复

void sig_chld(int signo)
{
pid_t pid;
int stat;

while((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf("child %d terminated\n", pid);
}
return;
}

int main(void)
{
int rc;

rc = 0;
signal(SIGCHLD, &sig_chld);
return (rc);
}

jluliuchao 2009-09-11
  • 打赏
  • 举报
回复
3. 通过sigaction系统调用指定信号SIGCHLD处理动作中的sa_flags为SA_NOCLDWAIT

用这种方法好像也不行啊,还是有僵尸进程.怎么办?
jluliuchao 2009-09-11
  • 打赏
  • 举报
回复
不好意思,刚才可能运行时间短,没发现,现在看到了很多僵尸进程。
看来直接忽略SIGCHLD还是不行,我再试试第三种方法
superbtl 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 superbtl 的回复:]
引用 3 楼 jluliuchao 的回复:
我用的signal(SIGCHLD,SIG_IGN)好像可以,还没有发现僵尸进程。
大家可以看看这篇文章:http://blog.chinaunix.net/u/5251/showart_435999.html
是不是在2.6内核中忽略SIGCHLD就行,而在2.4中就不行?
LZ是像父进程直接忽略了子进程结束的信号了,这样来说父进程也就是相当于处理了这个信号了。
我觉得应该可以
[/Quote]或者说直接让INIT进程去收养了? 这个我记也不清楚 期待~~
superbtl 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jluliuchao 的回复:]
我用的signal(SIGCHLD,SIG_IGN)好像可以,还没有发现僵尸进程。
大家可以看看这篇文章:http://blog.chinaunix.net/u/5251/showart_435999.html
是不是在2.6内核中忽略SIGCHLD就行,而在2.4中就不行?
[/Quote]LZ是像父进程直接忽略了子进程结束的信号了,这样来说父进程也就是相当于处理了这个信号了。
我觉得应该可以
superbtl 2009-09-11
  • 打赏
  • 举报
回复
避免僵尸进程要父进程wait子进程 或者直接把子进程由INIT进程管理
总归要有个进程收尸
你的父进程一直在(无法让子进程被INIT进程收养),而又不给子进程收尸就会产生了。

LS很全面了
jluliuchao 2009-09-11
  • 打赏
  • 举报
回复
我用的signal(SIGCHLD,SIG_IGN)好像可以,还没有发现僵尸进程。
大家可以看看这篇文章:http://blog.chinaunix.net/u/5251/showart_435999.html
是不是在2.6内核中忽略SIGCHLD就行,而在2.4中就不行?
linaxing 2009-09-11
  • 打赏
  • 举报
回复
避免产生僵尸进程的方法一般有:
1. fork两次,使得孙子进程的父亲为init,孙子进程去执行job
2. 制定自己的SIGCHLD信号处理函数,在这个信号处理函数中调用wait()
3. 通过sigaction系统调用指定信号SIGCHLD处理动作中的sa_flags为SA_NOCLDWAIT
challenge99 2009-09-11
  • 打赏
  • 举报
回复
忽略SIGCHILD后, 僵死进程并不一定会被INIT处理, 如果进程的父进程不是INIT

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧