in reply to forking subroutines?
Notice I never install a SIGCHLD handler. That is because the parent will process them itself. Also, the waitpids are done non-blocking. The sleep makes sure we do not loop too tightly.
As splinky said, if you call a subroutine, make sure it exits or you call exit after it returns. The original code I took this from actually exec'd and so I didn't worry about it.
$num_children is a command line arg, not shown here so you don't have to see my lame mp3 ripping code. It, obviously, controls how many child procs will be spawned.
# Interesting stuff has happened to load the job queue and par # the command line, and whatever else you want to happen. sub SPAWN { $counter++; if ( $cpid = fork ) { $tracker{$cpid} = $ref->[1]; } else { # This can be a call like this, or my_sub( @_ ); exit; # You can exec some external proc like # exec "/bin/ls -FC /var"; } } my $dpid = 0; while( @job_q ) { my $ref = shift @job_q; #-- # Initial loop to spawn children #-- if ( $counter < $num_children ) { &SPAWN( $ref ); } else { do { sleep 5; $dpid = waitpid( -1, 1 ); } until $dpid; last if ( $dpid == -1 ); # No children left printf "%s has finished, spawning next child (%d left)\n", $tr +acker{$dpi d}, scalar @job_q; &SPAWN( $ref ); } } do { sleep 5; $dpid = waitpid( -1, 1 ); printf("%s has finished\n", $tracker{$dpid}) if(defined( $tracker{ +$dpid} ) ); } until $dpid == -1;
I will warn you this isn't the most robust code. I haven't had problems with it, but it is something only I use. It is a slightly different solution to the problem though.
|
---|