fork() from a thread (pthreads)

  • Follow


 Hello,

  is it possible that a fork() from a thread 
  messes up local variables to the thread?

  i am having another problem which i cannot 
  explain otherwise than fork() damaging local
  variables.


P.Krumins

0
Reply Peteris 9/20/2003 5:57:04 PM

Hi Peteris, 

>   is it possible that a fork() from a thread 
>   messes up local variables to the thread?

Hmm... I doubt! Could you tell us a bit more? 

>   i am having another problem which i cannot 
>   explain otherwise than fork() damaging local
>   variables.

OTOH using fork() with threads is usually a bad, bad,
very bad idea! 

Oh, BTW. If you have Pthreads related questions, you might 
find the NG comp.programming.threads more adequate ;-)

Cheers,
Loic.

-- 
Article post� via l'acc�s Usenet http://www.mes-news.com 
Acc�s par Nnrp ou Web
0
Reply Loic 9/20/2003 7:46:50 PM


Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> writes:

>  Hello,
> 
>   is it possible that a fork() from a thread 
>   messes up local variables to the thread?
> 
>   i am having another problem which i cannot 
>   explain otherwise than fork() damaging local
>   variables.

Everything's possible (bugs happen).  But it should not.  Do checksums
before and after  fork (or keep a  copy) of all your data  to check if
that's  the problem.   The only  state that  should change  before and
after is the return value by fork().

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
0
Reply Pascal 9/20/2003 8:10:02 PM

Loic Domaigne <loic-dev@gmx.net> wrote in news:mW.HLJ2y2.nIJ@mes-
news.com:

> Hi Peteris, 
> 
>>   is it possible that a fork() from a thread 
>>   messes up local variables to the thread?
> 
> Hmm... I doubt! Could you tell us a bit more? 

There are some local variables to the thread handling function.
I have verified there are no race conditions which
could cause the variables to change.
If I dump the variables just before fork(), i see the correct
values, after fork() has succeeded and I am dumping variables
from the child process they have changed, and dumping after
fork() they remain changed and wrong (same as in child process).


If i remove the fork() call and everything following it
(child and parent handling code),
program works very correct even with lots of threads, as
it is expected to work!

>>   i am having another problem which i cannot 
>>   explain otherwise than fork() damaging local
>>   variables.
> 
> OTOH using fork() with threads is usually a bad, bad,
> very bad idea! 

Please elaborate.
 
> Oh, BTW. If you have Pthreads related questions, you might 
> find the NG comp.programming.threads more adequate ;-)
> 

Allright. My next question goes there.


P.Krumins
0
Reply Peteris 9/20/2003 8:16:01 PM

Pascal Bourguignon <spam@thalassa.informatimago.com> wrote in 
news:877k43w7ad.fsf@thalassa.informatimago.com:

> Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> writes:
> 
>>  Hello,
>> 
>>   is it possible that a fork() from a thread 
>>   messes up local variables to the thread?
>> 
>>   i am having another problem which i cannot 
>>   explain otherwise than fork() damaging local
>>   variables.
> 
> Everything's possible (bugs happen).  But it should not.  Do checksums
> before and after  fork (or keep a  copy) of all your data  to check if
> that's  the problem.   The only  state that  should change  before and
> after is the return value by fork().
> 

Please see my reply to Loic.

If i remove fork() part, everything works perfectly as is should (from
functional aspect).


P.Krumins
0
Reply Peteris 9/20/2003 8:30:36 PM

Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> wrote in 
news:Xns93FCEC8AE610Bwhitesuneapollolv@130.133.1.4:

> 
> If i remove the fork() call and everything following it
> (child and parent handling code),
> program works very correct even with lots of threads, as
> it is expected to work!
> 

I am correcting myself - it works perfectly from functional
aspect. Fork is required for program actually to do its
job.

Also i forgot to mention, that after the fork()'s been made,
the child calls exec*().


P.Krumins
0
Reply Peteris 9/20/2003 8:39:12 PM

>>> Peteris Krumins wrote:

>>>   is it possible that a fork() from a thread 
>>>   messes up local variables to the thread?
>> Hmm... I doubt! Could you tell us a bit more? 
PK> There are some local variables to the thread handling function.
PK> I have verified there are no race conditions which
PK> could cause the variables to change.

Do you mean values in thread local storage (accessible via
pthread_getspecific())?


-netch-
0
Reply Valentin 9/20/2003 8:56:55 PM

Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> writes:

>   is it possible that a fork() from a thread 
>   messes up local variables to the thread?

No.

However, fork()ing MT executables is an *extremely* tricky business,
and you'll be much better off forking all your children before you
create your first thread.

Also note, that forked child of MT executable can not (legally)
call any async-signal unsafe functions between the return from
fork(), and subsequent exec.

Cheers,
-- 
In order to understand recursion you must first understand recursion.
0
Reply Paul 9/20/2003 9:05:00 PM

Hello Peteris, 

> > OTOH using fork() with threads is usually a bad, bad,
> > very bad idea! 
> 
> Please elaborate.

So you want to know more about fork() and Pthreads? Here's a
simplified story.

Prior to the advent of Pthreads, fork() was really simple and well
understood. A process was in reality a single thread, and forking had
a well defined meaning: creating a new process whose image after the
fork() equals the one prior to the fork().

But then, Pthreads came. From a Pthreads point of view, a process is a
collection of threads. So the first natural question that arose was:
what does it mean when a thread fork()? Does it mean that only the
thread calling fork() exists it the child (this is call "fork one").
Or does it mean that the whole process must be forked, i.e. that all
threads exist in the child ("fork all")?

The POSIX guys opted for the "fork one" semantic, because it was
"simpler". Fine. But this approach had a major problem: the data
invariants accross the fork() are not necessarily protected. Indeed,
recall that fork() duplicates the  whole memory space, including
mutexes in their current locking state, but only the calling thread:
other threads are not running in the child process. Thus, if a mutex
is locked by a thread other than the thread calling fork, that  mutex 
will  remain  locked forever in the child process, possibly blocking
the execution of the child process.

To face to that problem, the POSIX guys introduced the famous
pthread_atfork(). The function pthread_atfork() allows you to install
fork handlers, in order to ensure the proper locking/unlocking of
mutexes accross fork(). So far, so good. The Pthreads interface, aka
Posix 1003.1c-1995, was released...

Some times after, David Butenhof (one of the Pthread masters), noticed
a big issue that have been sadly overlooked by the standard. Namely,
that fork() is defined in the list of async-signal-safe functions,
namely the functions than can be safely called in signal handlers. And
that's a problem, because if you install fork handlers, you might call
the pthread_mutex_* and none of the Pthreads interface is
async-signal-safe (for efficiency reasons).

This issue causes a lot of headaches to the POSIX guys, and if I
understood correctly, there is no portable way to ensure that the data
invariants are protected accross a fork(). A rule of thumb stated by
the POSIX guys is what
Paul explained: 

"any async-signal unsafe functions between the return from fork(), and
subsequent exec.Otherwise, the behavior might be undefined."

(As a matter of fact, this is a sufficient condition to ensure
portability, but not a necessary one. This might be weaken).


==========================================
A Mini-guide regarding fork() and Pthreads
==========================================

1- You DO NOT WANT to do that. 

2- If you needs to fork() then: whenever possible, fork() all your
childs prior to starting any threads.

3- If you need to fork() in a thread then: exec immediately a new
program in the child process.

4- Take care about reentrancy wrt. POSIX signals between the fork()
and the exec*()

Conclusion:

As stated humoristically by David Butenhof: 
"it is not polite to say to a thread: fork you!" ;-)


Regards,
Loic.
0
Reply loic 9/21/2003 10:33:41 AM

> >>>   is it possible that a fork() from a thread 
> >>>   messes up local variables to the thread?
> >> Hmm... I doubt! Could you tell us a bit more? 
> PK> There are some local variables to the thread handling function.
> PK> I have verified there are no race conditions which
> PK> could cause the variables to change.
> 
> Do you mean values in thread local storage (accessible via
> pthread_getspecific())?

That would be bad, indeed ;-)

It occurred to me that Peteris means the standard "local variable"
stored to the thread's stack. Peteris, is it correct?

Loic.
0
Reply loic 9/21/2003 11:21:30 AM

Hello! 

> >>   is it possible that a fork() from a thread 
> >>   messes up local variables to the thread?
> > 
> > Hmm... I doubt! Could you tell us a bit more? 
> 
> There are some local variables to the thread handling function.
>
> If I dump the variables just before fork(), i see the correct
> values, after fork() has succeeded and I am dumping variables
> from the child process they have changed, and dumping after
> fork() they remain changed and wrong (same as in child process).

I'm not a fork/exec expert, but if I understood correctly, you do not
have normally to care about the memory state because exec()  wipe out
the current process image... Except of course, if you need the value
of some variables for the exec() call. Am I right?

If you had the problem that the child hangs after forking, I would
understand... But that the local variables are messed up. That's
interesting!

You seems to say that prior to the fork(), the value of your variables
are OK, and after the fork() they are both wrong in the child and the
parent.

One question: are they consistently wrong? I mean the same wrong value
in the child and in the parent? (BTW, if you are using printf() or
variant in the child to print those values, you might not be surprised
if you get a SIGSEGV or something!).

> I have verified there are no race conditions which
> could cause the variables to change

Are you sure? If your local variables have the same values in the
parent and in the child, it might indicate that that value - for some
reason - changed in the parent prior to the process image duplication
performed by fork() (but after that you printed out the values).


Regards,
Loic.
0
Reply loic 9/21/2003 11:39:06 AM

loic-dev@gmx.net (Loic Domaigne) wrote in news:3e0374e6.0309210321.79193f69
@posting.google.com:

>> >>>   is it possible that a fork() from a thread 
>> >>>   messes up local variables to the thread?
>> >> Hmm... I doubt! Could you tell us a bit more? 
>> PK> There are some local variables to the thread handling function.
>> PK> I have verified there are no race conditions which
>> PK> could cause the variables to change.
>> 
>> Do you mean values in thread local storage (accessible via
>> pthread_getspecific())?
> 
> That would be bad, indeed ;-)
> 
> It occurred to me that Peteris means the standard "local variable"
> stored to the thread's stack. Peteris, is it correct?
> 

Sorry for the delay, was busy debugging.
Yes it is correct. I meant local variable to the threads stack.


P.Krumins
0
Reply Peteris 9/21/2003 7:24:16 PM

loic-dev@gmx.net (Loic Domaigne) wrote in 
news:3e0374e6.0309210233.2a14a9b@posting.google.com:

> Hello Peteris, 
> 
>> > OTOH using fork() with threads is usually a bad, bad,
>> > very bad idea! 
>> 
>> Please elaborate.
> 
> So you want to know more about fork() and Pthreads? Here's a
> simplified story.

Thanks for the great story of Pthreads. :)

Now i understand why it is unpolite to say "fork() you" to a
thread :)


> 
> Regards,
> Loic.


P.Krumins
0
Reply Peteris 9/21/2003 7:33:58 PM

Peteris Krumins wrote:

>> OTOH using fork() with threads is usually a bad, bad,
>> very bad idea!
> 
> Please elaborate.

According to Butenhof "Programming with POSIX Threads", in a multithreaded
program, calling fork() will cause all the other threads to disappear in
the child. No destructions or cleanups will happen. You won't be able to
access heap memory in the child, especially threadspecific data values on
the heap.

-- 
John L. Fjellstad

A: Top posting!
Q: What is the most irritating thing on Usenet?
0
Reply John 9/22/2003 8:18:36 AM

13 Replies
415 Views

(page loaded in 0.086 seconds)

Similiar Articles:











7/22/2012 3:39:33 AM


Reply: