即使有信号,fork / exec 也会离开僵尸进程
Fork / exec leaving zombie processes even with signal
我有一个守护程序 fork
s 本身,然后有一个无限循环检查系统条件,当满足某些条件时,它 运行s 一个命令。这些命令可以很长 运行ning,这意味着它们需要异步,所以我使用 fork
和 execvp
到 运行 命令。我的代码如下所示:
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);
}
一切正常,我的命令 运行 正常 - 但是,它会留下僵尸进程。这是我第一次尝试异步使用 fork
和 exec
,但我认为 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);
}
我有一个守护程序 fork
s 本身,然后有一个无限循环检查系统条件,当满足某些条件时,它 运行s 一个命令。这些命令可以很长 运行ning,这意味着它们需要异步,所以我使用 fork
和 execvp
到 运行 命令。我的代码如下所示:
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);
}
一切正常,我的命令 运行 正常 - 但是,它会留下僵尸进程。这是我第一次尝试异步使用 fork
和 exec
,但我认为 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);
}