`posix_spawn` looks interesting. I'm kind of scared about fork in a multi-threaded context -- I see very little discussion about what happens (especially if you have many threads executing I/O).
Is there anywhere to go to read about the interactions of threads with syscalls like `fork`?
It is specified by POSIX and SUSv4 [1], but it still hard to use safely. Only the forking thread will exist in the child process; assume that mutexes are in an unspecified state, including those you do not know about (for example those inside libc malloc).
Friends do not let friends fork in a multithreaded process. Prefork before spawning any threads if required.
The POSIX specification is one of the best resources, especially
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html and
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09
You can download the HTML copy for free. It's useful to have the HTML frames version locally as you can grep it, and it's easier to jump around from the navigation frame.
The Linux manual pages are generally atrocious. The more updated pages literally copy+paste the POSIX standard. Better to just go straight to it. And because the POSIX standard is so well written, I think it's better to refer to it first and only look to other resources when you have more particular questions unanswered or raised by the standard. There's too much cargo-cult advice out there, often written by people who have at best only a passing familiarity with the standard or actual implementations.
As always, when in doubt refer to the actual source code. That should always be possible with Linux.
Forking from a threaded process is doable and the standard and implementations are carefully written to make it possible and practical, though generally the only sensible thing to do is to exec another process. The posix_spawn implementation should do the right thing. But the posix_spawn API can be painful to use for non-trivial purposes, especially compared to the simplicity of fork+dup+close+exec. A good implementation to study is the implementation in musl libc. (glibc code is not for the faint of heart.)
Is there anywhere to go to read about the interactions of threads with syscalls like `fork`?