免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1167 | 回复: 0
打印 上一主题 下一主题

僵死进程及避免方法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-04 19:29 |只看该作者 |倒序浏览

                                1. 僵死进程
当一个程序创建的子进程比父进程提前结束,内核仍然保存一些它的信息以便父进程会需要它 -
比如,父进程可能需要检查子进程的退出状态。为了得到这些
信息,父进程调用‘wait()’;当这个调用发生,内核可以丢弃这些信息。
在子进程终止后到父进程调用‘wait()’前的时间里,子进程被称为‘僵死进程’ (‘zombie’)。(如果你用‘ps’,这个子进程会有一个‘Z’出现在它的
状态区里指出这点。)
也就是说,当子进程调用 do_exit() 后,子进程就终止了,与次进程相关联的所有资源都被释放掉了(假设进程是这些资源的唯一使用者)。 进程不可
运行,并处于TASK_ZOMBIE状态。它所占用的资源就是内核栈,thread_info结构和task_struct结构。此时进程存在的唯一目的就是向它的
父进程提供信息(子进程的退出代码,也就是exit()提供的,存储在task_struct中的exit_code成员)。父进程检索到信息后(通过wait()系统调用),
或者通知内核那是无关的信息后(在某些系统上,你可以指令系统你对子进程的退出状态没有兴趣,在SysV系统上,可以调用signal函数,
设置SIGCLD信号为 SIG_IGN,系统将不产生僵死进程,
详细说明参见>10.7节),  由进程所持有的剩余内存被释放,归还给系统使用。
2. 怎样避免僵死进程的出现需要却认父进程为每个子进程的终止调用‘wait()’(或者‘waitpid()’, ‘wait3()’,等等);
或者,在某些系统上,你可以指令系统你对子进程的退出状态没有兴趣。(译者注:在SysV系统上,可以调用signal函数,设置SIGCLD信号为
SIG_IGN,系统将不产生僵死进程, 详细说明参见>10.7节)。
另一种方法是两次‘fork()’,而且使紧跟的子进程直接退出,这样造成孙子进程变成孤儿进程(orphaned),从而init进程将负责清除它。欲获得做这个的程序,参看范例章节的函数‘fork2()’。
为了忽略子进程状态,你需要做下面的步骤(查询你的系统手册页以知道这是否正常工作):
         struct sigaction sa;
         sa.sa_handler = SIG_IGN;
     #ifdef SA_NOCLDWAIT
         sa.sa_flags = SA_NOCLDWAIT;
     #else
         sa.sa_flags = 0;
     #endif
         sigemptyset(&sa.sa_mask);
         sigaction(SIGCHLD, &sa, NULL);
      
如果这是成功的,那么‘wait()’函数集将不再正常工作;如果它们中任何一个被调用,它们将等待直到*所有*子进程已经退出,然后返回失败,并且
‘errno==ECHILD’。
另一个技巧是捕获SIGCHLD信号,然后使信号处理程序调用‘waitpid()’或 ‘wait3()’。参见范例章节的完整程序。
参考文献:
http://www.juntuan.net/hkbc/nixbc/unix/x178.htm
《APUE》
《LKD》

               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/64128/showart_1106165.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP