threaded, forked, rethreaded processes will deadlock

Julian Elischer julian at elischer.org
Fri Jan 9 09:39:38 PST 2009


Brian Fundakowski Feldman wrote:
> On Thu, Jan 08, 2009 at 11:09:16PM -0800, Julian Elischer wrote:
>> Brian Fundakowski Feldman wrote:
>>> On Thu, Jan 08, 2009 at 10:44:20PM -0500, Daniel Eischen wrote:
>>>> On Thu, 8 Jan 2009, Brian Fundakowski Feldman wrote:
>>>>
>>>>> It appears that the post-fork hooks for malloc(3) are somewhat broken such that
>>>>> when a threaded program forks, and then its child attempts to go threaded, it
>>>>> deadlocks because it already appears to have locks held.  I am not familiar
>>>>> enough with the current libthr/libc/rtld-elf interaction that I've been able
>>>>> to fix it myself, unfortunately.
>>>> There's really nothing to fix - according to POSIX you are only
>>>> allowed to call async-signal-safe functions in the child forked
>>>> from a threaded process.  If you are trying to do anything other
>>>> than that, it may or may not work on FreeBSD, but it is not
>>>> guaranteed and is not portable.
>>>>
>>>> The rationale is that what is the point of forking and creating
>>>> more threads, when you can just as easily create more threads in
>>>> the parent without forking?  The only reason to fork from a threaded
>>>> process is to call one of the exec() functions.
>>> Well, it worked until the last major set of changes to malloc.  For me, the point
>>> was that I was able to have transparent background worker threads in any program
>>> regardless of its architecture, using the standard pthread fork hooks.  Could you
>>> point me to the POSIX section covering fork and threads?  If it's really not
>>> supposed to work then that's fine, but there's an awful lot of code there dedicated
>>> to support going threaded again after a fork.
>>>
>> Practically, you can't go threaded again after a fork
>> (by which I mean creating new threads or use things
>> like mutexes etc.) in any posix system I know of.
>>
>> It would require that:
>>  The forking thread stop until:
>>   Every other thread has released every resource it owns
>>   and reports itself to be in a "safe quiescent state",
>>   or at least report every resource it owns, especially
>>   locks,
>>  and
>>  After the fork:
>>   The child, post fork, to take ownership of all
>>   of them, and free them.
>>
>> You might be able to do that in a simple
>> threaded program, but consider then that the libraries may have
>> threads running in them of which you are unaware, and that
>> some of the resources may interract with resources owned by the
>> forking thread.
>>
>> Add to this that there may be a signal thrown into this mix as well
>>
>> (signals are the bane of thread developement)
> 
> Well, I wouldn't mind showing all of you what I can of what I had been doing
> with the background threads -- it works pretty well modulo this particular
> malloc lock bug.  Due to it being inappropriate to share library resources
> between a child and parent for an open socket connection, I always considered
> the only "safe" behavior to be going single-threaded for the duration of the fork
> processes in both the parent and child, and the pthread_atfork(3) hooks have been
> sufficient to do so.


ahhhh
well going single threaded for the duration of the fork, changes 
everything!

> 



More information about the freebsd-hackers mailing list