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