tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: using of fork() in multithreaded application



Taylor R Campbell <riastradh%NetBSD.org@localhost> writes:

>> Date: Wed, 22 Jan 2025 16:47:13 +0100
>> From: Peter Skvarka <ps%softinengines.com@localhost>
>> 
>> I have two questions:
>> Is safe using of fork() in NetBSD 10.1 in mutlithreaded application ?
>
> Generally yes, with the caveat that it is difficult for applications
> to use correctly.

In 2010ish I saw a hard-to-find bug, the details of which are now fading
from memory.  I think it was some kind of lock taken in a routine that
was called after fork and before exec.  I think the program was python
and the lock was in libc's malloc. (This would have NetBSD 5 or 6.)

I'm pretty sure this wasn't pushed upstream because I thought upstream
(python) wouldn't want to deal with it, as it would hugely difficult for
them.

POSIX says:

   https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html

   "Consequently, to avoid errors, the child process may only execute
   async-signal-safe operations until such time as one of the exec
   functions is called."

It is not a safe assumption that authors of code you are running are
actually paying attention to POSIX.  The realistic assumption is that
there code usually works on Linux.

> For example, if you have any application-specific locks, you usually
> have to take them carefully in a pthread_atfork handler to avoid
> deadlock in the child.

We did that as a workaround, taking the malloc lock before fork and
releasing it afterwards.  Then it was available in the child.  I think
we had to add a lock/unlock entry point in libc for this.


So I would say to the OP's question:

  As far as we know NetBSD's threads/fork comply with POSIX.

  There is a huge amount of code out there that does not comply with
  POSIX's requiremnt to only use async-signal-safe calls after fork and
  before exec.

  Therefore I am not really surprised by this.
  


Home | Main Index | Thread Index | Old Index