I have a situation where I need to spawn a helper process from within a very large, multithreaded application, which I do not have complete control over.
Right now I'm using fork()
/exec()
. This works a lot of the time, but in some circumstances the child crashes weirdly before the exec()
happens. I'm suspecting this is because fork()
ing multithreaded applications is generally considered to be a Really Bad Idea.
I would really, really like a way to start a process atomically, without fork()
ing the parent: with all file descriptors closed, environment set up the way I want, CWD set, etc. This should avoid all the horror of fork()
ing my multithreaded parent app, and dealing with file descriptor inheritance, etc. posix_spawn()
should be ideal. Unfortunately, on Linux, posix_spawn()
is implemented using fork()
and exec()
...
vfork()
is defined to suspend the parent process until the child calls exec()
. This would appear to be more like what I want, but my understanding was that vfork()
is generally considered a historical relic these days and is equivalent to fork()
--- is this still the case?
What's the least bad way of dealing with this?
Note that:
This is on Linux. Java is involved, but all my code is in C.
Calling fork
should be safe if you limit yourself to "raw" system calls (syscall(SYS_fork)
, syscalll(SYS_execve, ...)
, etc.). Call into any glibc routine, and you'll be in a lot of trouble.
Calling vfork
is not at all what you want: only the thread that called vfork
is suspended, and other threads will continue to run (and in the same address space as the vforked child). This is very likely to complicate your life.
Calling clone
directly is possible, but exceedingly tricky. We have an implementation that allows for safe forking of child processes from multithreaded apps (unfortunately not open source). That code is very tricky, and surprisingly long.