【问题标题】:How can I prevent zombie child processes?如何防止僵尸子进程?
【发布时间】:2013-06-05 15:12:21
【问题描述】:

我正在编写一个使用fork() 为客户端连接生成处理程序的服务器。服务器不需要知道分叉的进程会发生什么——它们自己工作,当它们完成后,它们应该死掉而不是变成僵尸。有什么简单的方法可以做到这一点?

【问题讨论】:

标签: c posix zombie-process


【解决方案1】:

有几种方法,但在父进程中使用sigactionSA_NOCLDWAIT 可能是最简单的一种:

struct sigaction sigchld_action = {
  .sa_handler = SIG_DFL,
  .sa_flags = SA_NOCLDWAIT
};
sigaction(SIGCHLD, &sigchld_action, NULL);

【讨论】:

  • 更简单:signal(SIGCHLD, SIG_IGN);
【解决方案2】:

使用双叉。让您的孩子立即 fork 另一个副本并退出原始子进程。

http://thinkiii.blogspot.com/2009/12/double-fork-to-avoid-zombie-process.html

在我看来,这比使用信号更简单,也更容易理解。

void safe_fork()
{
  pid_t pid;
  if (!pid=fork()) {
    if (!fork()) {
      /* this is the child that keeps going */
      do_something(); /* or exec */
    } else {
      /* the first child process exits */
      exit(0);
    }
  } else {
    /* this is the original process */  
    /* wait for the first child to exit which it will immediately */
    waitpid(pid);
  }
}

【讨论】:

  • 但是,如果有人想查看进程树或类似的东西,这会搞砸的,对吧?
  • 不确定,但似乎很有可能。
  • 在 POSIX 系统上,子进程的父进程将被更改为 INIT (PID = 1),所以是的,进程树不会是你所期望的
  • 这是正确的吗?第二个子进程没有成为僵尸的事实取决于第一个子进程立即退出的事实。如果 do_something() 什么都不做怎么办?
  • 确保您可以根据需要添加某种门控机制。
【解决方案3】:

如何摆脱僵尸进程?

你不能像杀死一个普通进程一样用 SIGKILL 信号杀死僵尸进程,因为僵尸进程无法接收任何信号。所以养成一个好习惯很重要。

那么在编程的时候,如何去除大量的僵尸进程呢?根据上面的描述,子进程死亡时会向父进程发送 SIGCHLD 信号。默认情况下,系统会忽略这个信号,所以最好的方法是我们可以在信号处理函数中调用wait(),这样可以避免僵尸在系统中徘徊。 了解更多信息:http://itsprite.com/how-to-deep-understand-the-zombie-process-in-linux/

【讨论】:

    猜你喜欢
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2010-11-12
    • 1970-01-01
    • 2016-07-03
    • 2014-05-09
    相关资源
    最近更新 更多