I sometimes use the idiom where you fork off a child process, and
then have the child exec to run some other code, and then later
have the parent kill the child's pid to get rid of it. I've seen
some odd behavior on one of my machines, though, where the "exec"
changes the pid of the child, so the return from fork is no
longer the pid that I need to kill. The following code runs
differently on my workstation and my laptop, despite the fact
that they're both AMD64 machines running ubuntu jaunty, using
perl 5.10.0:
use warnings;
use strict;
$|=1;
my $cmd = q{
perl -e 'print "child: id after exec: $$\n";
print "child: sees processes...\n " ,
grep { m/perl/ }
`ps ax` , "\n";
'
};
print "parent: pre-fork id $$\n";
if ( my $pid = fork ) {
# this is parent code
print "parent: post-fork id $$\n";
print "parent: return from fork is: $pid\n";
sleep 3;
print "parent: still here, with id $$\n";
print "parent: sees processes...\n " ,
grep { m/perl/ }
`ps ax` , "\n";
} else {
# this is child code
die "cannot fork: $!" unless defined $pid;
print "child believes it is: $$\n";
exec( $cmd ) # replaces child with a new perl: pid shouldn't change,
+ right?
}
On the laptop, the child pid stays the same after the exec, but
on the workstation it increases by one. There's very little
difference between the two machines... the laptop is a
single-processor (Turion) and the workstation is a dual (a
dual-Opteron).
They are running slightly different kernel versions, though, the
workstation is "2.6.24-16-generic" and the laptop is
"2.6.27-9-generic".
Any ideas what this might be about? If you've got a minute,
could you please run the code I posted above and report back on
how it behaves for you?
On my workstation (the dual-Opteron) the results are something like this:
parent: pre-fork id 27516
child believes it is: 27517
child: id after exec: 27518
parent: post-fork id 27516
parent: return from fork is: 27517
child: sees processes...
27516 pts/1 S+ 0:00 /usr/bin/perl /home/doom/bin/testes-fork
+itude
27517 pts/1 S+ 0:00 sh -c perl -e 'print "child: id after ex
+ec: $$\n";? print "child: se
27518 pts/1 R+ 0:00 perl -e print "child: id after exec: $$\
+n";? print "child: sees proc
parent: still here, with id 27516
parent: sees processes...
27516 pts/1 R+ 0:00 /usr/bin/perl /home/doom/bin/testes-fork
+itude
On my laptop (the Turion) the reults are like so:
parent: pre-fork id 7253
child believes it is: 7254
parent: post-fork id 7253
parent: return from fork is: 7254
child: id after exec: 7254
child: sees processes...
7253 pts/3 S+ 0:00 /usr/bin/perl /home/doom/bin/testes-forki
+tude
7254 pts/3 R+ 0:00 perl -e print "child: id after exec: $$\n
+";? print "
parent: still here, with id 7253
parent: sees processes...
7253 pts/3 S+ 0:00 /usr/bin/perl /home/doom/bin/testes-forki
+tude
7254 pts/3 Z+ 0:00 [perl] <defunct>