xiaq
xiaq

Reputation: 804

Are all reentrant functions safe to use after fork()ing in a multithreaded(with pthreads) process?

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:

  1. When the main thread forks, the other threads may be in the middle of some library function call; forking doesn't copy the other threads, making the calls stuck forever;

  2. 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 a malloc call, the forked child process has effectively a malloc call stuck forever that can never recover. Same thing for printf, 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:

  1. If you called some non-entrant function f off the main thread in the parent process, the child process can not call f.

  2. malloc is non-reentrant.

Is this correct, meaning that all reentrant functions may be safely used after forking? 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.

Upvotes: 3

Views: 901

Answers (1)

xiaq
xiaq

Reputation: 804

As pointed out by @cnicutar, the article did mention that you can call async-safe functions after forking. And according to this article, reentrant functions are always async-free (but not the opposite), thus safe to call after forking.

That concludes my main question. I'll ask the additional question in another thread (no pun intended).

Updated: I asked the additional question here.

Upvotes: 2

Related Questions