我自己有一个守护程序 track user: -> { @user }
def send_email_testing user_id
@user = User.find user_id
####send email ......removed for clarity
,然后有一个无限循环检查系统条件,并在满足某些条件时运行命令。这些命令可以长期运行,这意味着它们需要异步,因此我使用fork
和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
应该忽略子级,让init进程获取它们。为什么这些僵尸仍然挥之不去?
答案 0 :(得分:2)
SIG_IGN
设置不会在fork()
中保留,因此您需要在子进程中使用产生所有命令的循环而不是原始父进程来调用signal(SIGCHLD, SIG_IGN);
。 / p>
#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);
}