axl163 has asked for the wisdom of the Perl Monks concerning the following question:

Hello again Perl Monks,
My goal is to fork only 2 processes at a time with a 3 second sleep after each launch. I am using ForkManager and the following is my code:
my $count = 0; foreach (@temp_files) { $count++; print "$program run #$count with temp file \"$_\"...\n"; my $pid = $pm->start and next; system("$program < $_ &"); #Run program located in $PATH sleep 3; if (($count%2) == 0) { print "even run number\n"; #somehow wait for the 2 children processes #$pm -> wait_all_children()? } $pm->finish; # Terminates the child process }
It appears that my $pid = $pm->start and next; launches the children almost instantaneously and my sleep is executed after all the children have launched. If this is the case, how do I limit and control the launching of children processes. Any advice would be greatly appreciated. Thanks.

Replies are listed 'Best First'.
Re: How would I add a pause b/t forks in <code>my $pid = $pm->start and next;</code>
by samtregar (Abbot) on Oct 27, 2005 at 17:39 UTC
    That next is running in the parent and that's why your loop creates children without pausing. Here's how to pause in the parent after each child is forked:

    my $pid = $pm->start; if ($pid) { # this code runs in the parent sleep 3; next; }

    -sam

Re: How would I add a pause b/t forks in my $pid = $pm->start and next;
by jasonk (Parson) on Oct 27, 2005 at 17:48 UTC

    In addition to just pausing before the next, you can also use the run_on_start callback to add a delay in the parent process.

    # add this before your foreach loop to sleep 3 seconds # between starting processes $pm->run_on_start(sub { sleep 3 });

    We're not surrounded, we're in a target-rich environment!
Re: How would I add a pause b/t forks in my $pid = $pm->start and next;
by salva (Canon) on Oct 27, 2005 at 18:41 UTC
    instead of P::FM, use Proc::Queue, it allows you to set a minimum time interval between forks:
    use Proc::Queue size => 2, delay => 3.0, qw(system_back); foreach(@temp_files) { system_back("$program < $_"); } 1 while wait != -1;
      I'd never seen Proc::Queue before and I must say it's pretty shocking. As though fork/wait/waitpid weren't complex enough it adds another layer of complexity on top of that! I can't imagine why anyone would use this instead of Paralell::ForkManager. Just looking at this code (from the synopsis) makes my teeth hurt:

      1 while waitpid(-1, WNOHANG)>0; # reaps childs

      -sam

        As though fork/wait/waitpid weren't complex enough it adds another layer of complexity on top of that

        Well, not really, Proc::Queue is completelly transparent, use it at the beginning of your script and then call fork, exit, etc. as ever.