SPUG:Child Processes
Brian Hatch
spug at ifokr.org
Tue Feb 18 11:38:18 CST 2003
(CC'ing this back to the spug list for general knowledge.)
> I feel brain dean here. Obviously I am missing something
> important. No doubt it is one of those things where you bang
> your head on the keyboard after finding out what it is.
>
> Here is an example I was using to test.
>
> #!/usr/bin/perl -w
>
> use POSIX qw(sys_wait_h);
>
> $PROG = "sleep";
> $X = 4;
> $CHILDREN = 1;
>
>
> # Start some child processes
>
> until ( $CHILDREN == $X ) {
> print "Number of Children is $CHILDREN\n";
> $T = ($CHILDREN + 10);
> print "Child $CHILDREN is sleeping for $T seconds\n";
> system("$PROG $T&");
> $CHILDREN++;
> }
>
> # wait until they finish
>
> while ( wait() != -1 ) {
> print "Waiting on the children to finish\n";
> sleep 5;
> }
Ahh! you're starting a background process via system. That's
the problem.
When you run system your perl script forks and runs the system
call in a child process. When you run $PROG in a child process,
that process is a grandchild from the perl script's point of view.
You can't wait for grandchildren.
Instead you either want to look for a nice perl module which
makes things easier, or do it the "old fashioned" way, which
is what I have the most experience with. Something like this:
until ($CHILDREN == $X) {
print "Number of children is $CHILDREN\n";
$T = ($CHILDREN + 10);
print "Child $CHILDREN is sleeping for $T seconds\n";
my $child_pid = fork();
if ( not defined $child_pid ) {
die "We can't fork - out of processes?"
}
if ( not $child_pid) {
# we're a child process
exec $PROG, $T;
# We could use 'system "$PROG, $T"' but
# I prefer avoiding system whenever possible
# since it spawns a shell unnecessarily, and
# if you're using user input the shell can be
# abused. Better to learn to use exec properly.
#
# Alternatively, you could use "system $PROG, $T"
# which does not spawn a shell (the command is
# supplied as separate arguments to system, not
# as a string.)
# If the exec works, no need for exit, but let's
# be safe - we don't want our child acting like
# our parent if the exec fails, or if we change
# exec to system, which *will* continue processing.
exit 0;
}
# if parent, just keep going
$CHILDREN++;
}
# Changed to a do/while loop so the print happens before we wait.
do {
print "Waiting on the children to finish\n";
#sleep 5;
# No need to wait usually - wait will block until a child
# is ready.
while ( wait() != -1 );
print "All kids done.\n";
Of course this is completely untested, but should work.
--
Brian Hatch Can I request
Systems and you to eat a
Security Engineer little more
http://www.ifokr.org/bri/ efficiently?
Every message PGP signed
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 240 bytes
Desc: not available
Url : http://mail.pm.org/pipermail/spug-list/attachments/20030218/349daf4f/attachment.bin
More information about the spug-list
mailing list