我希望在Linux上实现类似于CreateProcess的功能。我做了很多研究,发现"Fork off and die"方法使用双叉来在init下运行子进程。也就是说,允许孩子独立于父母进行操作。
因为父母需要返回有关新创建的子进程的信息(即pid,名称等),我需要知道我是否在我的代码中遇到了竞争条件。目前,我通过管道分叉并检索第二个fork的pid,然后等待第一个fork退出。
int child = 0;
int fd[2] = { 0, 0 };
if (pipe (fd) != 0)
return Process();
int pid = fork();
if (pid < 0)
return Process();
if (pid == 0) // Child
{
if (setsid() != -1)
{
child = fork();
if (child == 0)
{
umask (0); // Reset umask
close (0); // Close stdin
close (1); // Close stdout
close (2); // Close stderr
execvp ( ... );
_exit (0);
}
// Do I need waitpid (child) here?
}
// Write the child PID using the pipe
write (fd[1], &child, sizeof (child));
_exit (0);
}
else // Parent
{
// Read the child PID using the pipe
read (fd[0], &child, sizeof (child));
// Remove zombie process
waitpid (pid, nullptr, 0);
// Child must finish exec by this point
return Process (child);
// Also gets name
}
问题:
答案 0 :(得分:0)
第二个孩子不需要waitpid()
。当进程的父进程死亡时,init
进程将采用该进程,因此不会出现僵尸进程。
waitpid()
仅在退出时等待的孩子返回。在孩子中调用execvp()
意味着服务员等待,直到执行的程序死亡,因为这是孩子死亡的时候。
waitpid()
将获得流程的退出状态。这个过程实际退出的时间并不重要。
答案 1 :(得分:0)
(稍微澄清一下:你所谓的孩子,实际上是你的孙子。这个过程的孩子刚刚分手并死去。)
我是否需要第二个waitpid等待孩子完成执行?
你不能。它是你的孙子,你只能等待你的直接孩子。此外,由于您的孙子的父母已经去世,您的孙子现在已经被重新授予了init(因此它实际上是您的前孙子女)。
waitpid在调用exec后会返回吗?
Waitpid在给定的pid死亡/退出时返回,或者如果它已经是僵尸则立即返回。该孙女在孙子中被召唤。您的waitpid电话根本不关心您的直接孩子的流程(除非您使用的是仅限Linux的子级别子功能)。
即使在waitpid之前调用了exit或exec,waitpid也会返回吗?
Waitpid只有在等待pid(必须是你的直接孩子)已经死亡时才会返回。如果情况不是这样,它将会阻止。