即使有信号,fork / exec 也会离开僵尸进程

Fork / exec leaving zombie processes even with signal

我有一个守护程序 forks 本身,然后有一个无限循环检查系统条件,当满足某些条件时,它 运行s 一个命令。这些命令可以很长 运行ning,这意味着它们需要异步,所以我使用 forkexecvp 到 运行 命令。我的代码如下所示:

int main(int argc, char *argv[])
{
  signal(SIGCHLD, SIG_IGN);
  pid_t pid, sid;
  pid = fork();
  if (pid < 0)
  {
    exit(EXIT_FAILURE);
  }
  if (pid > 0)
  {
    exit(EXIT_SUCCESS);
  }
  umask(0);
  sid = setsid();
  if (sid < 0)
  {
    exit(EXIT_FAILURE);
  }
  if ((chdir("/")) < 0)
  {
    exit(EXIT_FAILURE);
  }
  while (1)
  {
    // Check conditions
    ...
    if (conditions_met)
    {
      pid_t pid2, sid2;
      pid2 = fork();
      if (pid2 == 0)
      {
        sid2 = setsid();
        // Define command_argv
        ...
        execvp(command_argv[0], command_argv);
      }
    }
  sleep(60);
  }
exit(EXIT_SUCCESS);
}

一切正常,我的命令 运行 正常 - 但是,它会留下僵尸进程。这是我第一次尝试异步使用 forkexec,但我认为 signal(SIGCHLD, SIG_IGN) 应该忽略子进程并让 init 进程获取它们。为什么这些丧尸还在徘徊?

SIG_IGN 设置不会在 fork() 中保留,因此您需要在子进程中调用 signal(SIGCHLD, SIG_IGN); 并使用生成所有命令的循环,而不是原始父进程.

#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
    pid_t pid, sid;
    pid = fork();
    if (pid < 0)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (pid > 0)
    {
        exit(EXIT_SUCCESS);
    }
    signal(SIGCHLD, SIG_IGN);
    umask(0);
    sid = setsid();
    if (sid < 0)
    {
        perror("setsid");
        exit(EXIT_FAILURE);
    }
    if ((chdir("/")) < 0)
    {
        perror("chdir");
        exit(EXIT_FAILURE);
    }
    while (1)
    {
        // Check conditions
        if (true)
        {
            pid_t pid2, sid2;
            pid2 = fork();
            if (pid2 == 0)
            {
                sid2 = setsid();
                // Define command_argv
                execlp("sleep", "sleep", "1", (char*)0);
            }
        }
        sleep(60);
    }
    exit(EXIT_SUCCESS);
}