# Perl replica of using a Barrier with a Timeout # https://superfastpython.com/multiprocessing-barrier-in-python/ use MCE::Simple -strict, -signatures; use MCE::Barrier; use Time::HiRes 'sleep'; use Try::Tiny; STDOUT->autoflush(1); sub task ($barrier, $number) { # generate a unique value and block for a moment my $value = rand() * 10; sleep($value); # report result say "Process ${number} done, got: ${value}"; # wait on all other processes to complete # my ($remaining, $error) = $barrier->wait; # or via exception handling try { $barrier->wait; } catch { # pass }; } sub main () { # create a barrier plus one for the main process my $barrier = MCE::Barrier->new(5 + 1); # create the worker processes spawn task($barrier, $_) for 1..5; # wait for all processes to finish # my ($remaining, $error) = $barrier->wait; # or via exception handling try { $barrier->wait(timeout => 5); say "All processes have their result"; } catch { # $_ = "Operation timed out ..." say "Some processes did not finish on time..."; }; # reap the worker processes sync; } main(); __END__ Process 2 done, got: 2.20488202831806 Process 1 done, got: 4.51354761681618 Some processes did not finish on time... Process 5 done, got: 5.27888526282371 Process 4 done, got: 7.58755085132183 Process 3 done, got: 9.89621643981994 #### # Perl replica of using a Barrier with an Action # https://superfastpython.com/multiprocessing-barrier-in-python/ use MCE::Simple -strict, -signatures; use MCE::Barrier; use Time::HiRes 'sleep'; STDOUT->autoflush(1); sub report () { # report once all processes are done say "All processes have their result"; } sub task ($barrier, $number) { # generate a unique value and block for a moment my $value = rand() * 10; sleep($value); # report result say "Process ${number} done, got: ${value}"; # wait on all other processes to complete my ($remaining, $error) = $barrier->wait; # an alternative to using the "action" argument if ($remaining == 0) { say "I, process ${number}, was last..."; } } sub main () { # create a barrier, not including the main process my $barrier = MCE::Barrier->new(5, before_release => \&report); # create the worker processes spawn task($barrier, $_) for 1..5; # reap the worker processes sync; } main(); __END__ Process 1 done, got: 1.25912054515542 Process 5 done, got: 2.02445819116296 Process 4 done, got: 4.33312377966107 Process 3 done, got: 6.64178936815919 Process 2 done, got: 8.9504549566573 All processes have their result I, process 2, was last... #### # Perl replica of Aborting a Barrier # https://superfastpython.com/multiprocessing-barrier-in-python/ use MCE::Simple -strict, -signatures; use MCE::Barrier; use Time::HiRes 'sleep'; use Try::Tiny; STDOUT->autoflush(1); sub task ($barrier, $number) { # generate a unique value and block for a moment my $value = rand() * 10; sleep($value); # report result say "Process ${number} done, got: ${value}"; # check if the result was "bad" if ($value > 8) { say "Process ${number} aborting..."; $barrier->abort; } else { # wait on all other processes to complete # my ($remaining, $error) = $barrier->wait; # or via exception handling try { $barrier->wait; } catch { # pass }; } } sub main () { # create a barrier plus one for the main process my $barrier = MCE::Barrier->new(5 + 1); # create the worker processes spawn task($barrier, $_) for 1..5; # wait for all processes to finish # my ($remaining, $error) = $barrier->wait; # or via exception handling try { $barrier->wait(); say "All processes have their result"; } catch { # $_ = "Barrier aborted ..." say "At least one process aborted due to bad results"; }; # reap the worker processes sync; } main(); __END__ Process 1 done, got: 1.12563261603103 Process 5 done, got: 1.89097026203857 Process 4 done, got: 4.19963585053669 Process 3 done, got: 6.5083014390348 Process 2 done, got: 8.81696702753292 Process 2 aborting... At least one process aborted due to bad results