问题
I'm looking to implement a function similar to CreateProcess but on Linux. I did a lot of research and found the "Fork off and die" approach which uses a double fork to run the child under init. That is, allow the child to operate independent of the parent.
Because the parent needs to return information about the newly created child process (i.e. pid, name, etc.) I need to know if I'm running into a race condition in my code. Currently, I fork and retrieve the second fork's pid via pipes then wait for the first fork to exit.
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
}
Questions:
- Do I need a second waitpid to wait for the child to finish the exec?
- Does waitpid return upon a call to exec?
- Does waitpid return even if exit or exec were called before waitpid?
回答1:
You do not need to waitpid()
on the second child. When a process's parent dies, the child will be adopted by the init
process, so there will not be a zombie process.
waitpid()
only returns after the child it waits on exits. A call to execvp()
in the child means the waiter waits until the program that was executed dies, since that is when the child would die.
waitpid()
will get the exit status of the process. It doesn't matter when the process actually exited.
回答2:
(A little clarification: what you're calling child, is actually your grandchild. It's the child of the process that just forked off and died.)
Do I need a second waitpid to wait for the child to finish the exec?
You can't. It's your grandchild and you can only wait on your direct children. Additionally, because your grandchild's parent has died, your grandchild has now been reparented to init (so it's actually your ex-grandchild).
Does waitpid return upon a call to exec?
Waitpid returns when the given pid dies/exits or immediately if it's already a zombie. The exec is called in the grandchild. Your waitpid calls are not at all not concerned with processes that aren't your direct children (unless you're using the Linux-only child-subreaper feature).
Does waitpid return even if exit or exec were called before waitpid?
Waitpid only ever returns when the waited on pid (which must be your direct child) is dead. If that's not yet the case, it will block.
来源:https://stackoverflow.com/questions/30200126/create-independent-process-in-linux