Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tcl8.5/Tclx8.4 fork doesn't work properly

59 views
Skip to first unread message

Daniel A. Mezentsev

unread,
Jan 1, 2008, 1:26:23 PM1/1/08
to
Hi folks,
I've updated my tcl installation 8.4-->8.5, not everything (tclx still 8.4)
and my project stopped to work. I did some investigation and found that
there are some problems with fork. Here is example of code which work just
fine under tcl8.4 (without thread support) and doesn't work under 8.5
(with thread support):

#!/usr/local/bin/tclsh

package require Tclx
# package require md5

namespace eval test {

}

proc test::md5 {} {
set procId [fork];
if { $procId != 0 } {
puts "Exiting parent process pid=[pid]";
return 0;
}
puts "Child process pid=[pid]"
# puts [::md5::md5 -hex
-file /var/named/zones/in-addr.arpa/0.249.24.in-addr.arpa]
return 0;
}

test::md5
exit 0

Under 8.5 child process is not gonna to finish:
[dan@king BIND]$ ./test.tcl
Child process pid=26488
Exiting parent process pid=26485
[dan@king BIND]$ ps ax | grep test.tcl
26488 pts/1 S 0:00 /usr/local/bin/tclsh ./test.tcl
26490 pts/1 S+ 0:00 grep test.tcl


Alexandre Ferrieux

unread,
Jan 1, 2008, 1:46:45 PM1/1/08
to
On Jan 1, 7:26 pm, "Daniel A. Mezentsev" <dmezent...@parasun.com>
wrote:

> Hi folks,
>         I've updated my tcl installation 8.4-->8.5, not everything (tclx still 8.4)
>         and my project stopped to work. I did some investigation and found that
>         there are some problems with fork. Here is example of code which work just
>         fine under tcl8.4 (without thread support) and doesn't work under 8.5
>         (with thread support):

Why use a threaded version under unix ? Threads and fork don't make a
happy blend.

-Alex

Daniel A. Mezentsev

unread,
Jan 1, 2008, 1:54:31 PM1/1/08
to
Alexandre Ferrieux wrote:

I know that threads + fork potentially can cause problems (seems like I hit
one of them). Is there workaround to solve this problem and use 8.5 with
threads support or I should recompile tcl with threads disabled. Apparently
this problem wider - why binary distribution has so obvious bug (or
feature ;-)).

Alexandre Ferrieux

unread,
Jan 1, 2008, 2:23:30 PM1/1/08
to
On Jan 1, 7:54 pm, "Daniel A. Mezentsev" <dmezent...@parasun.com>

Sure, but keeping orthogonal things orthogonal is a nice habit. Here
you changed simultaneously the version and the thread support... So
did you try with 8.4-threads ?

-Alex

Daniel A. Mezentsev

unread,
Jan 1, 2008, 2:56:23 PM1/1/08
to
No, I didn't try 8.4 with enabled threads (need to recompile tcl).
Don't want to do it but seems like I have to recompile, but something is
telling me that enabling threads in 8.4 will bring me to the same unusable
results. I'll let you about my results.

Daniel A. Mezentsev

unread,
Jan 1, 2008, 3:12:03 PM1/1/08
to
As I expected, tcl 8.4 with threads support doesn't work properly with fork.
Child process is waiting for something.
strace -p <pid> shows the following
[dan@king BIND]$ strace -p 4849
Process 4849 attached - interrupt to quit
futex(0x8f4a8c4, FUTEX_WAIT, 3, NULL <unfinished ...>
Process 4849 detached

Seems like there is a bug. Who should take a look at this issue ? Somebody
from tcl core devs ?

David Gravereaux

unread,
Jan 1, 2008, 4:13:08 PM1/1/08
to
Daniel A. Mezentsev wrote:
> As I expected, tcl 8.4 with threads support doesn't work properly with fork.

IMHO, threads are portable, but fork() is not. I think it might come
down to you choosing either methodology as mutually exclusive.

I think this fork vs threads debate dates back to 2001 if I remember
right when Dave Welton flailed the big red flags about how pthreads and
fork just don't and can't mix.

Daniel A. Mezentsev

unread,
Jan 1, 2008, 4:46:06 PM1/1/08
to
David Gravereaux wrote:

> Daniel A. Mezentsev wrote:
>> As I expected, tcl 8.4 with threads support doesn't work properly with
>> fork.
>
> IMHO, threads are portable, but fork() is not. I think it might come
> down to you choosing either methodology as mutually exclusive.

Perhaps like fast solution of this issue I'll recompile 8.5 without threads,
but for long term ... hm, I don't know yet.


>
> I think this fork vs threads debate dates back to 2001 if I remember
> right when Dave Welton flailed the big red flags about how pthreads and
> fork just don't and can't mix.

I was a russian post grad student in 2001 in deep siberian city, so it's
really hard for me to operate with historical data. Actually it doesn't
clear for me - why fork+threads blend cause such problem. We don't have
same issue using C/C++, do we ? I have pretty simple perl program with the
same structure (parent -- fork -- parent + child -- parent exit -- child)
and it works just fine, honestly saying I'm not sure about threads support
in perl. Is is a bad tcl design ?

Michael Schlenker

unread,
Jan 1, 2008, 4:59:42 PM1/1/08
to
Daniel A. Mezentsev schrieb:

> As I expected, tcl 8.4 with threads support doesn't work properly with fork.
> Child process is waiting for something.
> strace -p <pid> shows the following
> [dan@king BIND]$ strace -p 4849
> Process 4849 attached - interrupt to quit
> futex(0x8f4a8c4, FUTEX_WAIT, 3, NULL <unfinished ...>
> Process 4849 detached
>
> Seems like there is a bug. Who should take a look at this issue ? Somebody
> from tcl core devs ?
>
Basically its a know issue. Tcl has a notifier thread running before the
fork and this does not survive the fork.

See:
http://sourceforge.net/tracker/index.php?func=detail&aid=1470152&group_id=10894&atid=110894

Michael

George Peter Staplin

unread,
Jan 1, 2008, 6:34:13 PM1/1/08
to
Daniel A. Mezentsev wrote:
> Hi folks,
> I've updated my tcl installation 8.4-->8.5, not everything (tclx still 8.4)
> and my project stopped to work. I did some investigation and found that
> there are some problems with fork. Here is example of code which work just
> fine under tcl8.4 (without thread support) and doesn't work under 8.5
> (with thread support):

We had a recent thread about this that I started.

http://groups.google.com/group/comp.lang.tcl/msg/ce6a1324bada8db0

It's basically unfixable IMO, unless the contraints are changed, and
even then it's iffy.


George

Donal K. Fellows

unread,
Jan 1, 2008, 8:33:58 PM1/1/08
to
Daniel A. Mezentsev wrote:
> why fork+threads blend cause such problem.

As I understand it, the problem relates to mutexes and the way Tcl needs
a thread to manage the notifier.

> We don't have same issue using C/C++, do we ?

Actually, you do the problems but you have enough control that you can
often sidestep them.

> I have pretty simple perl program with the
> same structure (parent -- fork -- parent + child -- parent exit -- child)
> and it works just fine, honestly saying I'm not sure about threads support
> in perl.

IIRC, perl is usually built unthreaded. They also don't use a notifier,
and so avoid a lot of complexity in that area (at the cost of not having
a notifier of course).

> Is is a bad tcl design ?

The problem is purely that the pthread library and the fork syscall are
not happy bed-fellows, and there's not much Tcl can do about it (since
threaded Tcl uses a number of threads internally). Now, it isn't
actually a problem when the fork is followed by an exec (all the
dangling lock problems get swept away by starting another executable)
but for other uses of fork are just trouble. If you insist on using them
together (e.g. because you're wanting to run as a daemon) then you
should write a small program to stand instead of tclsh that does the
forking and only then hands off control to the Tcl library.

(There are ways to make fork work for real; they're horrific.)

Donal.

Jeff Hobbs

unread,
Jan 1, 2008, 9:26:41 PM1/1/08
to
On Jan 1, 10:26 am, "Daniel A. Mezentsev" <dmezent...@parasun.com>
wrote:

> I've updated my tcl installation 8.4-->8.5, not everything (tclx still 8.4)
> and my project stopped to work. I did some investigation and found that
> there are some problems with fork. Here is example of code which work just
> fine under tcl8.4 (without thread support) and doesn't work under 8.5
> (with thread support):

The thread has the key points, but to summarize:

This has nothing to do with 8.4 vs 8.5, it is purely a pthreads+fork
issue. It isn't unique to Tcl. It is solvable *with constraints*. I
think the constraints are reasonable though (you use either fork()
*or* threads, but not both, and we would try and best support the
fork() case with the minimally threaded Tcl). There is dev effort
involved to make it work.

Jeff

Bezoar

unread,
Jan 1, 2008, 11:40:07 PM1/1/08
to
On Jan 1, 12:26 pm, "Daniel A. Mezentsev" <dmezent...@parasun.com>
wrote:

As a work around you can have the parent wait for the child to exit,
using wait . Alternatively, you can also set up a SIGCHLD handler
in the parent to do a wait to clean up the child. Accepting/handling
the SIGCHLD signal will prevent zombies from being created..
To get the child to exit have it send itself a signal. I have tried
only the default SIGTERM see kill in tclx man page and
the child cleans up and the parent is able to capture its exit
status. I tried this on my linux box and it workd fine.
The only draw back is if you wanted to know the real exit status of
the child then you would have to come up with another means to
comunicate that to the parent. ( like write to a file or pipe or
socket ) .

Carl

#!/bin/sh
# the next line restarts using wish \
exec /opt/usr/bin/tclsh8.5 "$0" ${1+"$@"}

package require Tclx
# package require md5

# this is how to use signals in Tclx trap a signal(s) and call command
the signal is subst into %s befor eval
#signal trap { SIGUSR1} [list sigUser1 %S ]
#proc sigUser1 { signal } {
# puts "[pid] got signal $signal"
# kill [pid]
#}
proc bye { } {
# kill yourself and OS will clean up
kill [ pid ]
}

namespace eval test {

}

proc test::md5 {} {
set procId [fork];
if { $procId != 0 } {
puts "Exiting parent process pid=[pid]";

puts "[wait -untraced $procId ]"


return 0;
}
puts "Child process pid=[pid]"
# puts [::md5::md5 -hex -file /var/named/zones/in-addr.arpa/
0.249.24.in-addr.arpa]

# after child calls this it will not return parent will get
sigterm signal for exit status
bye
}

test::md5
puts "Parent out of test"

exit 0

0 new messages