免费注册 查看新帖 |

Chinaunix

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

僵死进程是怎么产生得???? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-31 13:50 |只看该作者 |倒序浏览
对于信号不怎么了解,看到这么一行:
signal(SIGCLD,SIG_IGN);    /* 避免子进程在退出后变为僵死进程 */
谁能给解释解释这一行得意思啊??
僵死进程不是在父进程里面没有调用wait吗??

论坛徽章:
0
2 [报告]
发表于 2006-08-31 14:14 |只看该作者
子进程虽退出,但在进程表中仍占了一个位置,状态信息返回给了父进程,若父进程没对其进行处理就成了僵尸进程,signal(SIGCLD,SIG_IGN)是最简单的处理,不过也达到了释放资源的目的。但是如果父进程先于子进程结束,超级进程便会回收资源。也就是说,如果子进程先于父进程结束,必须做相应的处理,在服务程序里比较典型

论坛徽章:
0
3 [报告]
发表于 2006-08-31 15:24 |只看该作者
通俗点说是死了没人埋,专业点说是SIGCLD信号没处理

论坛徽章:
0
4 [报告]
发表于 2006-08-31 15:28 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
5 [报告]
发表于 2006-08-31 15:58 |只看该作者
如果子进程先终止,而父进程没有取其终止状态就僵死了

论坛徽章:
0
6 [报告]
发表于 2006-08-31 16:07 |只看该作者
哈哈, 我记得我原来理解这个时, 也是理解成:

儿子死了, 老爸活着都不去收尸, 儿子就成僵尸了.

论坛徽章:
0
7 [报告]
发表于 2006-08-31 17:05 |只看该作者
通俗点说是死了没人埋,专业点说是SIGCLD信号没处理
这个说法好像不对吧????
signal(SIGCLD,SIG_IGN)是最简单的处理,不过也达到了释放资源的目的
这个说法应该是对的

论坛徽章:
0
8 [报告]
发表于 2006-08-31 21:59 |只看该作者
How do I get rid of zombie processes that persevere?

--------------------------------------------------------------------------------

>From: casper@fwi.uva.nl (Casper Dik)
Date: Thu, 09 Sep 93 16:39:58 +0200


3.13) How do I get rid of zombie processes that persevere?

      Unfortunately, it's impossible to generalize how the death of
      child processes should behave, because the exact mechanism varies
      over the various flavors of Unix.

      First of all by default, you have to do a wait() for child
      processes under ALL flavors of Unix.  
That is, there is no flavor
      of Unix that I know of that will automatically flush child
      processes that exit, even if you don't do anything to tell it to
      do so.

      Second, under some SysV-derived systems, if you do
      "signal(SIGCHLD, SIG_IGN)" (well, actually, it may be SIGCLD
      instead of SIGCHLD, but most of the newer SysV systems have
      "#define SIGCHLD SIGCLD" in the header files), then child
      processes will be cleaned up automatically, with no further
      effort in your part.  
The best way to find out if it works at
      your site is to try it, although if you are trying to write
      portable code, it's a bad idea to rely on this in any case.
      Unfortunately, POSIX doesn't allow you to do this; the behavior
      of setting the SIGCHLD to SIG_IGN under POSIX is undefined, so
      you can't do it if your program is supposed to be
      POSIX-compliant.

      So, what's the POSIX way? As mentioned earlier, you must
      install a signal handler and wait. Under POSIX signal handlers
      are installed with sigaction. Since you are not interested in
      ``stopped'' children, only in terminated children, add SA_NOCLDSTOP
      to sa_flags.  Waiting without blocking is done with waitpid().
      The first argument to waitpid should be -1 (wait for any pid),
      the third should be WNOHANG. This is the most portable way
      and is likely to become more portable in future.


      If your systems doesn't support POSIX, there's a number of ways.
      The easiest way is signal(SIGCHLD, SIG_IGN), if it works.
      If SIG_IGN cannot be used to force automatic clean-up, then you've
      got to write a signal handler to do it.  It isn't easy at all to
      write a signal handler that does things right on all flavors of
      Unix, because of the following inconsistencies:

      On some flavors of Unix, the SIGCHLD signal handler is called if
      one *or more* children have died.  This means that if your signal
      handler only does one wait() call, then it won't clean up all of
      the children.  Fortunately, I believe that all Unix flavors for
      which this is the case have available to the programmer the
      wait3() or waitpid() call, which allows the WNOHANG option to
      check whether or not there are any children waiting to be cleaned
      up.  Therefore, on any system that has wait3()/waitpid(), your
      signal handler should call wait3()/waitpid() over and over again
      with the WNOHANG option until there are no children left to clean
      up. Waitpid() is the preferred interface, as it is in POSIX.

      On SysV-derived systems, SIGCHLD signals are regenerated if there
      are child processes still waiting to be cleaned up after you exit
      the SIGCHLD signal handler.  Therefore, it's safe on most SysV
      systems to assume when the signal handler gets called that you
      only have to clean up one signal, and assume that the handler
      will get called again if there are more to clean up after it
      exits.

      On older systems, there is no way to prevent signal handlers
      from being automatically reset to SIG_DFL when the signal
      handler gets called.  On such systems, you have to put
      "signal(SIGCHILD, catcher_func)" (where "catcher_func" is the
      name of the handler function) as the last thing in the signal
      handler, so that it gets reset.

      Fortunately, newer implementations allow signal handlers to be
      installed without being reset to SIG_DFL when the handler
      function is called.  To get around this problem, on systems that
      do not have wait3()/waitpid() but do have SIGCLD, you need to
      reset the signal handler with a call to signal() after doing at
      least one wait() within the handler, each time it is called.  For
      backward compatibility reasons, System V will keep the old
      semantics (reset handler on call) of signal().  Signal handlers
      that stick can be installed with sigaction() or sigset().

      The summary of all this is that on systems that have waitpid()
      (POSIX) or wait3(), you should use that and your signal handler
      should loop, and on systems that don't, you should have one call
      to wait() per invocation of the signal handler.

      One more thing -- if you don't want to go through all of this
      trouble, there is a portable way to avoid this problem, although
      it is somewhat less efficient.  Your parent process should fork,
      and then wait right there and then for the child process to
      terminate.  The child process then forks again, giving you a
      child and a grandchild.  The child exits immediately (and hence
      the parent waiting for it notices its death and continues to
      work), and the grandchild does whatever the child was originally
      supposed to.  Since its parent died, it is inherited by init,
      which will do whatever waiting is needed.  This method is
      inefficient because it requires an extra fork, but is pretty much
      completely portable.

[ 本帖最后由 westgarden 于 2006-9-1 02:45 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2006-09-01 00:22 |只看该作者
不错

论坛徽章:
0
10 [报告]
发表于 2006-09-01 05:28 |只看该作者
英语学的不好
有点迷糊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP