【问题标题】:Fork / exec leaving zombie processes even with signalFork / exec 即使有信号也会离开僵尸进程
【发布时间】:2019-09-01 13:03:08
【问题描述】:

我自己有一个守护程序forks,然后有一个无限循环检查系统条件,当满足某些条件时,它运行一个命令。这些命令可以长时间运行,这意味着它们需要是异步的,所以我使用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 进程获得它们。为什么这些僵尸还在徘徊?

【问题讨论】:

    标签: c signals fork exec zombie-process


    【解决方案1】:

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 2019-10-19
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      相关资源
      最近更新 更多