in reply to Parallel::ForkManager and stack

my @keycards= qw(A B C); my @users = qw(peter james john luke andrew judas); ... foreach my $user (@users) { sleep(int(rand(3))); my $key = pop(@keycards); $pm->start and next;
as been said, it's a race condition.
  1. peter pops keycard and starts
  2. james pops keycard and starts
  3. john pops keycard and starts
  4. luke pops keycards. It starts if one (or more) of peter, james or john has already finished. Otherwise it waits for one of them to quit. But what kind of keycard does it have?
Fixing the problems with forks (or threads) by randomly inserting calls to sleep is a TERRIBLE idea. Just don't ever do it!

It seems to me this problem could be solved by

my $pm = Parallel::ForkManager->new(2);
or, more generally
my $pm = Parallel::ForkManager->new(@keycards - 1);
All in all, that looks like a fairly questionable, error-prone feature of Parallel::ForkManager (which is a good module otherwise).

Replies are listed 'Best First'.
Re^2: Parallel::ForkManager and stack
by ikegami (Patriarch) on Jan 27, 2016 at 19:00 UTC

    Better solution (since it allows all keycards to be in use at the same time):

    foreach my $user (@users) { $pm->wait_one_child() while !@keycards; <----- my $key = pop(@keycards); $pm->start and next; print "$user took the '$key' key\n"; $pm->finish(0, { key => $key }); } $pm->wait_all_children;
      thanks to both of you. I didn't know about wait_one_child(), (and only realized how to use wait_for_available_procs() after seeing your post). This solves my problem