I'm working on a C++ project which employs pthreads for multithreading, but also needs to fork
now and then. I've read warnings scattered in the code that memory allocation should never be done after fork
, but I didn't know exactly why before I found this article. I've summarized the points:
When the main thread
fork
s, the other threads may be in the middle of some library function call;fork
ing doesn't copy the other threads, making the calls stuck forever;malloc
uses global variable, and employs locks to achieve thread safety. So if one of threads of the parent process happen to be in the middle in amalloc
call, thefork
ed child process has effectively amalloc
call stuck forever that can never recover. Same thing forprintf
, etc.
I realized that this has something to do with reentrancy, a term that is not mentioned in the article. It seems that the claim is equivalent to:
If you called some non-entrant function
f
off the main thread in the parent process, the child process can not callf
.malloc
is non-reentrant.
Is this correct, meaning that all reentrant functions may be safely used after fork
ing? Or am I still missing some nasty corners of how pthreads and traditional UNIX process model interact?
If I am right, there is another question: malloc
is known to be non-reentrant, but what about C++'s new
? I googled for that with not many relevant results (mostly due to the difficulty to hit the correct "new" :), but there is at least one claim that new
is reentrant. There is also a relevant question concerning the whole C++ standard library with no satisfying answer.
PS. For the interested, the C++ project is the fish shell. Forking is definitely needed for shells, and threads are employed to improve responsiveness.