Please refer to the Open Group specifications for this. fork duplicates
the process memory image, but does not duplicate the threads themselves. I
take that to mean the memory other than for the pthread itself will be
“duplicated”, and that if the only reference to said memory (directly or
indirectly) was on a stack frame for a thread that got left behind, then
the memory will be orphaned.
On Wed, Dec 14, 2016 at 1:57 PM, Karan, Cem F CIV USARMY RDECOM ARL (US) <
cem.f.karan.civ@xxxxxxxx> wrote:
Makes sense. I can see how the standard library calls are difficult to
deal with; you have no control over how that memory is allocated. I'm
going to expose my ignorance here; does fork() duplicate structures
allocated by pthreads? I know it duplicates file descriptors, but I don't
know what else it duplicates. Off hand, do you know of a complete list of
what fork() duplicates?
Thanks,
Cem Karan
-----Original Message-----On Behalf Of Garrett D'Amore
From: nanomsg-bounce@xxxxxxxxxxxxx [mailto:nanomsg-bounce@xxxxxxxxxxxxx]
Sent: Wednesday, December 14, 2016 2:31 PMfork()-safe implementation
To: nanomsg@xxxxxxxxxxxxx
Subject: [nanomsg] Re: [Non-DoD Source] Re: On pthread_atfork(), and
the identity of the sender, and confirm the authenticity of all links
All active links contained in this email were disabled. Please verify
contained within the message prior to copying and pasting the address toa Web browser.
that happens after fork() is exec(). (In which case the whole image is
________________________________
Initially, I’m not handling it at all… the expectation is that the thing
replaced, so it does not matter.) If you reenter the library in thechild after the fork, the library will “panic” — emit an error message to
stderr, and call abort(). Essentially I’m making it explicit that thisoperation is verboten.
where we completely reinitialize the library in the child, I’ll need to use
In the future, if I ever do the work to make this really fork safe,
a
different allocator. I can either track all memory objects allocatedvia my nni_alloc() routine on a linked list, or if I have an allocator that
lets me manage the entire arena, I can just discard the arena. Thelatter is preferable in that it eliminates a lot of overhead, and I don’t
have to figure out how to keep track of the structures allocatedseparately.
having to block fork operation except when I grow the arena. But
If I have an arena based approach, or slab based approach, I can avoid
when I do, or on every alloc/free if I keep a global linked list, I’dhave to acquire a resource that blocks fork (such as a reader writer lock,
that is acquired in write mode in prefork(), and released in parent().)investing any time in it at present, now that I’ve verified that there is
This is a fair bit of complexity, for an uncommon use case, so I’m not
a clear path to making this work in my implementation if there is aneed. Btw, this same approach could be used with nanomsg currently
— you’d just basically have to provide an alternate implementation fornn_alloc() and nn_free(). With these the linked list approach looks
not so bad since they are already doing some fairly dirty things underthe covers.
library for underlying things like pthread structures or internal
Note that this will do *nothing* to recover memory allocated by the C
buffers used for open files. You can see why the problem is ratherthorny — so much so that the POSIX committee was convinced to
abandon efforts to solve it.(US) <cem.f.karan.civ@xxxxxxxx < Caution-
On Wed, Dec 14, 2016 at 10:37 AM, Karan, Cem F CIV USARMY RDECOM ARL
mailto:cem.f.karan.civ@xxxxxxxx ;> > wrote:the fork()? I'm curious to see what you're going to do.
As you wish. Can you post how you handle the memory leaks after
nanomsg-bounce@xxxxxxxxxxxxx > [Caution-mailto:nanomsg-
Thanks,
Cem Karan
> -----Original Message-----
> From: nanomsg-bounce@xxxxxxxxxxxxx < Caution-mailto:
bounce@xxxxxxxxxxxxx < Caution-mailto:nanomsg-bounce@xxxxxxxxxxxxx ;> ]On Behalf Of Garrett D'Amore
> Sent: Wednesday, December 14, 2016 10:57 AMand fork()-safe implementation
> To: nanomsg@xxxxxxxxxxxxx < Caution-mailto:nanomsg@xxxxxxxxxxxxx
> Subject: [nanomsg] Re: [Non-DoD Source] Re: On pthread_atfork(),
>verify the identity of the sender, and confirm the authenticity of all
> All active links contained in this email were disabled. Please
linksaddress to a Web browser.
> contained within the message prior to copying and pasting the
>can keep track of my own objects. (Kind of critical when you
>
> ________________________________
>
>
>
> Yeah…um… as an operating system engineer, I generally believe I
work insidethe *size* of the object with the object at free() time. This is to
> a kernel.) In fact, in libnng I require that the system provide
permitrequirement exists in the Solaris kernel.) It also allows the use of
> porting to platforms where this is a requirement. (Such a
much muchto stash the size with the object (which is often automatically
> more efficient allocators, like slab allocators, and not having
known atimprove the odds of having your object aligned on a natural
> *compile* time), so you save quite a bit of lookup, and can
boundary (such asthis effort, and so a GC is kind of out of the question.
> a page).
>
> Portability to embedded systems is really important to me in
>mwpowellhtx@xxxxxxxxx < Caution-mailto:mwpowellhtx@xxxxxxxxx ;> <
>
> On Wed, Dec 14, 2016 at 6:50 AM, Michael Powell <
Caution-Caution-mailto:mwpowellhtx@xxxxxxxxx ;< Caution-mailto:mwpowellhtx@xxxxxxxxx > > > wrote:
>RDECOM ARL
>
> On Wed, Dec 14, 2016 at 9:07 AM, Karan, Cem F CIV USARMY
> (US) <cem.f.karan.civ@xxxxxxxx < Caution-mailto:cem.f.karan.civ@xxxxxxxx > < Caution-Caution-
mailto:cem.f.karan.civ@xxxxxxxx ;< Caution-mailto:cem.f.karan.civ@xxxxxxxx > > > wrote:
> > Have you considered using a garbage collector? E.g.Caution-Caution-http://www.hboehm.info/gc/ ;< Caution-
http://www.hboehm.info/gc/ ;> < Caution-info/gc/ > > . Looking through the header file, it appears
> Caution-http://www.hboehm.info/gc/ ;< Caution-http://www.hboehm.
that there are calls specifically for handling forksGC_atfork_child(), and GC_start_mark_threads()). Based on
> (GC_set_handle_fork(), GC_atfork_prepare(), GC_atfork_parent(),
thethat the collector can handle fork()s that are not followed by
> documentation surrounding GC_start_mark_threads(), it appears
an exec().functions to register finalization methods, so that should handle
> That may solve the memory leak issues cleanly. There are also
dealingpoor coding
> with file pointers, etc. that you want to close eventually.
>
> What does a GC gain you, but to make further excuses for
> practices, in the first place? Been there, done that,don't need
> another T-shirt.is quite fast; I allocate a ridiculous number of short-lived objects, and
>
>
> > I use that particular collector in my own work, and it
even1% of the runtime. I've never tried forking a child though, so I
> then, the profiler shows that garbage collection takes less than
don't knownanomsg-bounce@xxxxxxxxxxxxx > < Caution-Caution-
> how well that part works.
> >
> > Thanks,
> > Cem Karan
> >
> >> -----Original Message-----
> >> From: nanomsg-bounce@xxxxxxxxxxxxx < Caution-mailto:
mailto:nanomsg-bounce@xxxxxxxxxxxxx ;< Caution-mailto:nanomsg-bounce@freelists.org > > [Caution-Caution-mailto:nanomsg- ;<
Caution-mailto:nanomsg- ;>Caution-Caution-mailto:nanomsg-bounce@xxxxxxxxxxxxx ;<
> bounce@xxxxxxxxxxxxx < Caution-mailto:bounce@xxxxxxxxxxxxx ;> <
Caution-mailto:nanomsg-bounce@xxxxxxxxxxxxx ;> > ] On Behalf Of GarrettD'Amore
> >> Sent: Wednesday, December 14, 2016 1:53 AMfreelists.org > < Caution-Caution-mailto:nanomsg@xxxxxxxxxxxxx ;<
> >> To: nanomsg@xxxxxxxxxxxxx < Caution-mailto:nanomsg@
Caution-mailto:nanomsg@xxxxxxxxxxxxx ;> >pthread_atfork(), and fork()-safe implementation
> >> Subject: [Non-DoD Source] [nanomsg] Re: On
> >>Please verify the identity of the sender, and confirm the authenticity
> >> All active links contained in this email were disabled.
of allpasting the address to a Web browser.
> links
> >> contained within the message prior to copying and
> >>number of hours this evening trying to bake in a solution. I eventually
> >>
> >> ________________________________
> >>
> >>
> >>
> >> Well I thought I had a brilliant idea, and I spent a
had tothat leaks *only* any memory used by mutexes and condvars. That’s
> throw my
> >> hands up in the air.
> >>
> >> I can see that it *is* possible to build a solution
definitelyextreme, and it requires you to basically build the equivalent of an
> possible.
> >> The problem is, the work you have to do for this is
operatingregions fork-safe vs. unsafe, etc. The problem is that in order
> system in
> >> some ways. I had a scheme to suspend threads, and mark
toin every single memory object in your system has to be
> avoid leaking
> >> memory, you pretty *have* to manage your own heap — as
globallyalso want to build your own memory manager, since some memory
> discoverable.
> >> This turns out to be rather inconvenient if you don’t
> objects are goingwere “orphaned” in that they didn’t have any global state to them,
> >> to be used by threads, and frankly I had objects that
onlymemory manager that will let me reclaim every allocated object in
> locally used
> >> inside functions in threads.
> >>
> >> One day I may come back to this, by supplying my own
thefell swoop). I’d also need a way to reclaim files, and handle mutexes
> system
> >> (perhaps simply by reclaiming the entire heap in one
andand that it can be done in the platform layer. Which means it can be
> condvars
> >> “magically”. I’m pretty sure I know how to do that,
donedecide I’m willing to take the larger action to stop using “ordinary”
> in the
> >> future, as a fairly straight-forward retrofit, once I
memorymeantime, that I’m taking my earlier action, which is to panic when
> >> management. I’ve got enough other stuff to do in the
thefork().
> user
> >> attempts to reenter the library from the child after
> >>garrett@xxxxxxxxxx < Caution-mailto:garrett@xxxxxxxxxx ;> <
> >> - Garrett
> >>
> >>
> >> On Tue, Dec 13, 2016 at 8:51 AM, Garrett D'Amore <
Caution-Caution-mailto:garrett@xxxxxxxxxx ;< Caution-mailto:garrett@xxxxxxxxxx > > < Caution-
> Caution-Caution-mailto:garrett@xxxxxxxxxx ;< Caution-mailto:garrett@xxxxxxxxxx > < Caution-Caution-
mailto:garrett@xxxxxxxxxx ;< Caution-mailto:garrett@xxxxxxxxxx ;> > > >wrote:
> >>version of things in the new design. I had implemented freeze and thaw
> >>
> >> Thanks. I had planned to design a fork safe
andthis would have worked well. Until I discovered that the child side
> reset
> >> entry points at various points and was pretty sure that
> version was notchild side action might be reasonable and lead to a working solution.
> >> allowed to call any mutex functions or to call free.
> >>
> >> I will think about this some more. Delaying the
> >>franklinmathieu@xxxxxxxxx < Caution-
> >> Sent from my iPhone
> >>
> >>
> >> > On Dec 13, 2016, at 12:20 AM, Franklin Mathieu <
mailto:franklinmathieu@xxxxxxxxx ;> < Caution-franklinmathieu@xxxxxxxxx > > < Caution-Caution-Caution-
> Caution-mailto:franklinmathieu@xxxxxxxxx ;< Caution-mailto:
mailto:franklinmathieu@xxxxxxxxx ;< Caution-mailto:franklinmathieu@gmail.com > < Caution-
franklinmathieu@xxxxxxxxx > > >
> Caution-mailto:franklinmathieu@xxxxxxxxx ;< Caution-mailto:
> >> > wrote:was the one that initially
> >> >
> >> > I'm going to give my 2 cents on the matter as I
> >> > opened the github issue regarding fork()-safetyand I had the time
> >> > to work with different approaches on the matter.for C that relies on
> >> >
> >> > I've been maintaining an unit testing framework
> >> > worker processes to run tests safely, and assuch, for the longest
> >> > time, this had been implemented with fork()without a subsequent exec().
> >> > I recently switched the I/O layer of theframework to use nanomsg
> >> > because it was simple, and it was much more"correct" than what
> >> > I had been doing before with pipe() shenanigans.swab at implementing
> >> >
> >> > However, as nanomsg isn't fork()-safe, I took a
> >> > a fork()-safety mechanism, which ended up beingbrittle but was
> >> > "good enough" for my purposes, and I reworkedother dependencies
> >> > to make sure they handled forks correctly.you think of it right at the
> >> >
> >> > The problem with fork()-safety is that unless
> >> > design of the software, you're going to end updoing something hack-ish;
> >> > which means that the rewrite could be a goodstarting point to actually
> >> > implement the structural basis towardsfork()-safety. POSIX might be
> >> > right on target with the problems caused bypthread_atfork(), but in
> >> > practice there is a lot of wiggle room to dowhat we must to make
> >> > things work at fork.myself on fork()-safety.
> >> >
> >> > With all of that being said, I've given up
> >> > The fact is that there is no single silverbullet to address this,
> >> > that a lot of software is expecting exec() tobe called after a fork(),
> >> > and that there aren't many use cases in havingworker processes.
> >> >spawning worker
> >> > I ended up writing a library dedicated to
> >> > processes [1] in a manner that calls fork()then re-exec()s the current
> >> > executable with a patched main function, whichwhile not ideal, is
> >> > in my opinion less of a hack than having tomake the software and
> >> > all of its dependencies fork-safe().giving up and panicking
> >> >
> >> > This is why I understand your decision of
> >> > the process on fork-reentry. You might also beable to compromise
> >> > by only allowing calls to nng_socket_createafter fork, which could under
> >> > the covers completely drop the current invalidstate and just reinitialize
> >> > the library. This would cause a resource leak,but allow the usage
> >> > of sockets in the child for those that reallywant it.
> >> >//github.com/diacritic/BoxFort < Caution-https://github.com/
> >> > [1]: Caution-Caution-Caution-https:
diacritic/BoxFort >
< Caution-Caution-https://github.com/diacritic/BoxFort ;< Caution-https://github.com/diacritic/BoxFort ;> > < Caution-
> Caution-Caution-https://github.com/diacritic/BoxFort ;< Caution-https://github.com/diacritic/BoxFort ;> < Caution-Caution-
https://github.com/diacritic/BoxFort ;< Caution-https://github.com/diacritic/BoxFort > > >
> >> >garrett@xxxxxxxxxx < Caution-mailto:garrett@xxxxxxxxxx ;> <
> >> > 2016-12-12 19:31 GMT+01:00 Garrett D'Amore <
Caution-Caution-mailto:garrett@xxxxxxxxxx ;< Caution-mailto:garrett@xxxxxxxxxx > > <
> Caution-Caution-Caution-mailto:garrett@xxxxxxxxxx ;<Caution-mailto:garrett@xxxxxxxxxx ;> < Caution-Caution-
mailto:garrett@xxxxxxxxxx ;< Caution-mailto:garrett@xxxxxxxxxx ;> > > >:fork() with nanomsg (or future
> >> >> The following conversation relates to using
> >> >> rewrites), where you do *not* immediately callexec(). Using fork() and
> >> >> then immediately calling exec() is fine, andwill continue to work as it
> >> >> always.children, e.g. a child worker
> >> >>
> >> >> But some people want to use fork() to spawn
> >> >> process, that communicates back to the parentsomehow. This is never going
> >> >> to work.pthread_atfork() as part of an
> >> >>
> >> >> I’ve been doing a bit more research into
> >> >> attempt to make my new nng library properlyfork()-safe. I’ve more or less
> >> >> given up though.has given up — see
> >> >>
> >> >> The reason for this is that even the OpenGroup
> >> >> Caution-Caution-Caution-http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html <
Caution-http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html > < Caution-
> Caution-http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html < Caution-
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html > > < Caution-
> >> Caution-Caution-http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html < Caution-
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html > < Caution-
> Caution-http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html < Caution-
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html > > >
> >> >> — and especially the RATIONALE section, forthe logic behind this. They
> >> >> have even indicated plans to deprecate thepthread_atfork() API altogether.
> >> >>version of the library fork() safe
> >> >> Essentially, it isn’t possible to make a
> >> >> as it would be necessary to free resources, dolocks, etc. — i.e. all those
> >> >> Async-Signal-Unsafe calls.libnanomsg, I will be
> >> >>
> >> >> So, for libnng, and possibly in the future for
> >> >> changing the API so that if you attempt tocallback into the library after
> >> >> fork(), it will actually panic the process.pthread_atfork() to be called to close any
> >> >>
> >> >> I probably will also arrange for
> >> >> file descriptors that were not markedclose-on-exec…
> >> >>< Caution-https://diacritic.io ;> < Caution-Caution-https://diacritic.io ;<
> >> >> Stay tuned for more details.
> >> >>
> >> >> - Garrett
> >> >
> >> >
> >> > --
> >> > Franklin "Snaipe" Mathieu
> >> > 🝰 Caution-Caution-Caution-https://diacritic.io
Caution-https://diacritic.io ;> > < Caution-Caution-Caution-https://diacritic.io < Caution-https://diacritic.io ;> < Caution-
> Caution-https://diacritic.io ;< Caution-https://diacritic.io ;>
>
> >> >
> >>
> >>
> >
>
>
>