Provided by: libparallel-forkmanager-perl_2.02-1_all bug

NAME

       Parallel::ForkManager - A simple parallel processing fork manager

VERSION

       version 2.02

SYNOPSIS

         use Parallel::ForkManager;

         my $pm = Parallel::ForkManager->new($MAX_PROCESSES);

         DATA_LOOP:
         foreach my $data (@all_data) {
           # Forks and returns the pid for the child:
           my $pid = $pm->start and next DATA_LOOP;

           ... do some work with $data in the child process ...

           $pm->finish; # Terminates the child process
         }

DESCRIPTION

       This module is intended for use in operations that can be done in parallel where the number of processes
       to be forked off should be limited. Typical use is a downloader which will be retrieving
       hundreds/thousands of files.

       The code for a downloader would look something like this:

         use LWP::Simple;
         use Parallel::ForkManager;

         ...

         my @links=(
           ["http://www.foo.bar/rulez.data","rulez_data.txt"],
           ["http://new.host/more_data.doc","more_data.doc"],
           ...
         );

         ...

         # Max 30 processes for parallel download
         my $pm = Parallel::ForkManager->new(30);

         LINKS:
         foreach my $linkarray (@links) {
           $pm->start and next LINKS; # do the fork

           my ($link, $fn) = @$linkarray;
           warn "Cannot get $fn from $link"
             if getstore($link, $fn) != RC_OK;

           $pm->finish; # do the exit in the child process
         }
         $pm->wait_all_children;

       First you need to instantiate the ForkManager with the "new" constructor.  You must specify the maximum
       number of processes to be created. If you specify 0, then NO fork will be done; this is good for
       debugging purposes.

       Next, use $pm->start to do the fork. $pm returns 0 for the child process, and child pid for the parent
       process (see also "fork()" in perlfunc(1p)).  The "and next" skips the internal loop in the parent
       process. NOTE: $pm->start dies if the fork fails.

       $pm->finish terminates the child process (assuming a fork was done in the "start").

       NOTE: You cannot use $pm->start if you are already in the child process.  If you want to manage another
       set of subprocesses in the child process, you must instantiate another Parallel::ForkManager object!

METHODS

       The comment letter indicates where the method should be run. P for parent, C for child.

       new $processes
            Instantiate  a  new Parallel::ForkManager object. You must specify the maximum number of children to
            fork off. If you specify 0 (zero), then no children will be forked. This is intended  for  debugging
            purposes.

            The  optional  second  parameter,  $tempdir,  is  only  used if you want the children to send back a
            reference to some data (see RETRIEVING DATASTRUCTURES below). If not provided, it is set via a  call
            to File::Temp::tempdir().

            The new method will die if the temporary directory does not exist or it is not a directory.

            Since version 2.00, the constructor can also be called in the typical Moo/Moose fashion. I.e.

                my $fm = Parallel::ForkManager->new(
                    max_procs => 4,
                    tempdir => '...',
                    child_role => 'Parallel::ForkManager::CustomChild',
                );

       child_role
            Returns  the  name  of  the  role consumed by the ForkManager object in child processes. Defaults to
            Parallel::ForkManager::Child and can be set to something else via the constructor.

       start [ $process_identifier ]
            This method does the fork. It returns the pid of the child process for the parent,  and  0  for  the
            child  process.  If  the  $processes parameter for the constructor is 0 then, assuming you're in the
            child process, $pm->start simply returns 0.

            An optional $process_identifier can be provided to this method... It is used by the  "run_on_finish"
            callback (see CALLBACKS) for identifying the finished process.

       start_child [ $process_identifier, ] \&callback
            Like  "start",  but  will run the &callback as the child. If the callback returns anything, it'll be
            passed as the data to transmit back to the parent process via "finish()".

       finish [ $exit_code [, $data_structure_reference] ]
            Closes the child process by exiting and accepts an optional exit code (default exit code is 0) which
            can be retrieved in the parent via callback.  If the second  optional  parameter  is  provided,  the
            child  attempts  to  send  its  contents  back  to  the parent. If you use the program in debug mode
            ($processes == 0), this method just calls the callback.

            If the $data_structure_reference is provided, then  it  is  serialized  and  passed  to  the  parent
            process. See RETRIEVING DATASTRUCTURES for more info.

       set_max_procs $processes
            Allows you to set a new maximum number of children to maintain.

       wait_all_children
            You  can  call  this method to wait for all the processes which have been forked. This is a blocking
            wait.

       reap_finished_children
            This is a non-blocking call to reap children and execute callbacks independent of calls  to  "start"
            or  "wait_all_children".  Use  this  in scenarios where "start" is called infrequently but you would
            like the callbacks executed quickly.

       is_parent
            Returns "true" if within the parent or "false" if within the child.

       is_child
            Returns "true" if within the child or "false" if within the parent.

       max_procs
            Returns the maximal number of processes the object will fork.

       running_procs
            Returns the pids of the forked processes currently monitored by  the  "Parallel::ForkManager".  Note
            that  children  are still reported as running until the fork manager harvest them, via the next call
            to "start" or "wait_all_children".

                my @pids = $pm->running_procs;

                my $nbr_children =- $pm->running_procs;

       wait_for_available_procs( $n )
            Wait until $n available process slots are available.  If $n is not given, defaults to 1.

       waitpid_blocking_sleep
            Returns the sleep period, in seconds, of the pseudo-blocking  calls.  The  sleep  period  can  be  a
            fraction of second.

            Returns 0 if disabled.

            Defaults to 1 second.

            See BLOCKING CALLS for more details.

       set_waitpid_blocking_sleep $seconds
            Sets the the sleep period, in seconds, of the pseudo-blocking calls.  Set to 0 to disable.

            See BLOCKING CALLS for more details.

CALLBACKS

       You  can define callbacks in the code, which are called on events like starting a process or upon finish.
       Declare these before the first call to start().

       The callbacks can be defined with the following methods:

       run_on_finish $code [, $pid ]
           You can define a subroutine which is called when a child is terminated. It is called  in  the  parent
           process.

           The parameters of the $code are the following:

             - pid of the process, which is terminated
             - exit code of the program
             - identification of the process (if provided in the "start" method)
             - exit signal (0-127: signal name)
             - core dump (1 if there was core dump at exit)
             - datastructure reference or undef (see RETRIEVING DATASTRUCTURES)

       run_on_start $code
           You  can  define a subroutine which is called when a child is started. It called after the successful
           startup of a child in the parent process.

           The parameters of the $code are the following:

             - pid of the process which has been started
             - identification of the process (if provided in the "start" method)

       run_on_wait $code, [$period]
           You can define a subroutine which is called when the child process needs to wait for the startup.  If
           $period  is not defined, then one call is done per child. If $period is defined, then $code is called
           periodically and the module waits for $period seconds between the two calls.  Note,  $period  can  be
           fractional  number  also.  The exact "$period seconds" is not guaranteed, signals can shorten and the
           process scheduler can make it longer (on busy systems).

           The $code called in the "start" and the "wait_all_children" method also.

           No parameters are passed to the $code on the call.

BLOCKING CALLS

       When it comes to waiting for child processes to terminate, "Parallel::ForkManager" is between a fork  and
       a  hard  place  (if  you excuse the terrible pun). The underlying Perl "waitpid" function that the module
       relies on can block until either one specific or any child process terminate, but not for a process  part
       of a given group.

       This  means  that  the  module  can  do one of two things when it waits for one of its child processes to
       terminate:

       Only wait for its own child processes
           This is done via a loop using a "waitpid" non-blocking call and a sleep  statement.   The  code  does
           something along the lines of

               while(1) {
                   if ( any of the P::FM child process terminated ) {
                       return its pid
                   }

                   sleep $sleep_period
               }

           This  is  the  default behavior that the module will use.  This is not the most efficient way to wait
           for child processes, but it's the safest way to ensure that "Parallel::ForkManager"  won't  interfere
           with any other part of the codebase.

           The sleep period is set via the method "set_waitpid_blocking_sleep".

       Block until any process terminate
           Alternatively,  "Parallel::ForkManager"  can  call  "waitpid" such that it will block until any child
           process terminate. If the child process was not one of the  monitored  subprocesses,  the  wait  will
           resume.  This  is  more  efficient, but mean that "P::FM" can captures (and discards) the termination
           notification that a different part of the code might be waiting for.

           If  this  is  a  race  condition  that  doesn't  apply  to   your   codebase,   you   can   set   the
           waitpid_blocking_sleep period to 0, which will enable "waitpid" call blocking.

               my $pm = Parallel::ForkManager->new( 4 );

               $pm->set_waitpid_blocking_sleep(0);  # true blocking calls enabled

               for ( 1..100 ) {
                   $pm->start and next;

                   ...; # do work

                   $pm->finish;
               }

RETRIEVING DATASTRUCTURES from child processes

       The ability for the parent to retrieve data structures is new as of version 0.7.6.

       Each child process may optionally send 1 data structure back to the parent.  By data structure, we mean a
       reference  to  a  string,  hash or array. The contents of the data structure are written out to temporary
       files on disc using the Storable modules' store() method. The reference is then retrieved from within the
       code you send to the run_on_finish callback.

       The data structure can be any scalar perl data structure which makes sense: string, numeric  value  or  a
       reference to an array, hash or object.

       There are 2 steps involved in retrieving data structures:

       1)  A  reference  to  the  data  structure the child wishes to send back to the parent is provided as the
       second argument to the finish() call. It is up to the child to decide whether or  not  to  send  anything
       back to the parent.

       2) The data structure reference is retrieved using the callback provided in the run_on_finish() method.

       Keep  in  mind  that data structure retrieval is not the same as returning a data structure from a method
       call. That is not what actually occurs. The data  structure  referenced  in  a  given  child  process  is
       serialized  and  written  out to a file by Storable. The file is subsequently read back into memory and a
       new data structure belonging to the parent process is created. Please consider the performance penalty it
       can imply, so try to keep the returned structure small.

EXAMPLES

   Parallel get
       This small example can be used to get URLs in parallel.

         use Parallel::ForkManager;
         use LWP::Simple;

         my $pm = Parallel::ForkManager->new(10);

         LINKS:
         for my $link (@ARGV) {
           $pm->start and next LINKS;
           my ($fn) = $link =~ /^.*\/(.*?)$/;
           if (!$fn) {
             warn "Cannot determine filename from $fn\n";
           } else {
             $0 .= " " . $fn;
             print "Getting $fn from $link\n";
             my $rc = getstore($link, $fn);
             print "$link downloaded. response code: $rc\n";
           };
           $pm->finish;
         };

   Callbacks
       Example of a program using callbacks to get child exit codes:

         use strict;
         use Parallel::ForkManager;

         my $max_procs = 5;
         my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
         # hash to resolve PID's back to child specific information

         my $pm = Parallel::ForkManager->new($max_procs);

         # Setup a callback for when a child finishes up so we can
         # get it's exit code
         $pm->run_on_finish( sub {
             my ($pid, $exit_code, $ident) = @_;
             print "** $ident just got out of the pool ".
               "with PID $pid and exit code: $exit_code\n";
         });

         $pm->run_on_start( sub {
             my ($pid, $ident)=@_;
             print "** $ident started, pid: $pid\n";
         });

         $pm->run_on_wait( sub {
             print "** Have to wait for one children ...\n"
           },
           0.5
         );

         NAMES:
         foreach my $child ( 0 .. $#names ) {
           my $pid = $pm->start($names[$child]) and next NAMES;

           # This code is the child process
           print "This is $names[$child], Child number $child\n";
           sleep ( 2 * $child );
           print "$names[$child], Child $child is about to get out...\n";
           sleep 1;
           $pm->finish($child); # pass an exit code to finish
         }

         print "Waiting for Children...\n";
         $pm->wait_all_children;
         print "Everybody is out of the pool!\n";

   Data structure retrieval
       In this simple example, each child sends back a string reference.

         use Parallel::ForkManager 0.7.6;
         use strict;

         my $pm = Parallel::ForkManager->new(2, '/server/path/to/temp/dir/');

         # data structure retrieval and handling
         $pm -> run_on_finish ( # called BEFORE the first call to start()
           sub {
             my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;

             # retrieve data structure from child
             if (defined($data_structure_reference)) {  # children are not forced to send anything
               my $string = ${$data_structure_reference};  # child passed a string reference
               print "$string\n";
             }
             else {  # problems occurring during storage or retrieval will throw a warning
               print qq|No message received from child process $pid!\n|;
             }
           }
         );

         # prep random statement components
         my @foods = ('chocolate', 'ice cream', 'peanut butter', 'pickles', 'pizza', 'bacon', 'pancakes', 'spaghetti', 'cookies');
         my @preferences = ('loves', q|can't stand|, 'always wants more', 'will walk 100 miles for', 'only eats', 'would starve rather than eat');

         # run the parallel processes
         PERSONS:
         foreach my $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) {
           $pm->start() and next PERSONS;

           # generate a random statement about food preferences
           my $statement = $person . ' ' . $preferences[int(rand @preferences)] . ' ' . $foods[int(rand @foods)];

           # send it back to the parent process
           $pm->finish(0, \$statement);  # note that it's a scalar REFERENCE, not the scalar itself
         }
         $pm->wait_all_children;

       A second datastructure retrieval example demonstrates how children decide whether or not to send anything
       back, what to send and how the parent should process whatever is retrieved.

         use Parallel::ForkManager 0.7.6;
         use Data::Dumper;  # to display the data structures retrieved.
         use strict;

         my $pm = Parallel::ForkManager->new(20);  # using the system temp dir $L<File::Temp::tempdir()

         # data structure retrieval and handling
         my %retrieved_responses = ();  # for collecting responses
         $pm -> run_on_finish (
           sub {
             my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;

             # see what the child sent us, if anything
             if (defined($data_structure_reference)) {  # test rather than assume child sent anything
               my $reftype = ref($data_structure_reference);
               print qq|ident "$ident" returned a "$reftype" reference.\n\n|;
               if (1) {  # simple on/off switch to display the contents
                 print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\n\n|;
               }

               # we can also collect retrieved data structures for processing after all children have exited
               $retrieved_responses{$ident} = $data_structure_reference;
             } else {
               print qq|ident "$ident" did not send anything.\n\n|;
             }
           }
         );

         # generate a list of instructions
         my @instructions = (  # a unique identifier and what the child process should send
           {'name' => '%ENV keys as a string', 'send' => 'keys'},
           {'name' => 'Send Nothing'},  # not instructing the child to send anything back to the parent
           {'name' => 'Childs %ENV', 'send' => 'all'},
           {'name' => 'Child chooses randomly', 'send' => 'random'},
           {'name' => 'Invalid send instructions', 'send' => 'Na Na Nana Na'},
           {'name' => 'ENV values in an array', 'send' => 'values'},
         );

         INSTRUCTS:
         foreach my $instruction (@instructions) {
           $pm->start($instruction->{'name'}) and next INSTRUCTS;  # this time we are using an explicit, unique child process identifier

           # last step in child processing
           $pm->finish(0) unless $instruction->{'send'};  # no data structure is sent unless this child is told what to send.

           if ($instruction->{'send'} eq 'keys') {
             $pm->finish(0, \join(', ', keys %ENV));

           } elsif ($instruction->{'send'} eq 'values') {
             $pm->finish(0, [values %ENV]);  # kinda useless without knowing which keys they belong to...

           } elsif ($instruction->{'send'} eq 'all') {
             $pm->finish(0, \%ENV);  # remember, we are not "returning" anything, just copying the hash to disc

           # demonstrate clearly that the child determines what type of reference to send
           } elsif ($instruction->{'send'} eq 'random') {
             my $string = q|I'm just a string.|;
             my @array = qw(I am an array);
             my %hash = (type => 'associative array', synonym => 'hash', cool => 'very :)');
             my $return_choice = ('string', 'array', 'hash')[int(rand 3)];  # randomly choose return data type
             $pm->finish(0, \$string) if ($return_choice eq 'string');
             $pm->finish(0, \@array) if ($return_choice eq 'array');
             $pm->finish(0, \%hash) if ($return_choice eq 'hash');

           # as a responsible child, inform parent that their instruction was invalid
           } else {
             $pm->finish(0, \qq|Invalid instructions: "$instruction->{'send'}".|);  # ordinarily I wouldn't include invalid input in a response...
           }
         }
         $pm->wait_all_children;  # blocks until all forked processes have exited

         # post fork processing of returned data structures
         for (sort keys %retrieved_responses) {
           print qq|Post processing "$_"...\n|;
         }

USING RAND() IN FORKED PROCESSES

       A caveat worth noting is that all forked  processes  will  use  the  same  random  seed,  so  potentially
       providing                    the                    same                   results                   (see
       <http://blogs.perl.org/users/brian_phillips/2010/06/when-rand-isnt-random.html>).   If  you   are   using
       "rand()" and want each forked child to use a different seed, you can add the following to your program:

           $pm->run_on_start(sub { srand });

EXTENDING

       As of version 2.0.0, "Parallel::ForkManager" uses Moo under the hood. When a process is being forked from
       the   parent   object,   the   forked   instance   of   the  object  will  be  modified  to  consume  the
       Parallel::ForkManager::Child role. All of this makes extending  Parallel::ForkManager  to  implement  any
       storing/retrieving mechanism or any other behavior fairly easy.

   Example: store and retrieve data via a web service
           {
               package Parallel::ForkManager::Web;

               use HTTP::Tiny;

               use Moo;
               extends 'Parallel::ForkManager';

               has ua => (
                   is => 'ro',
                   lazy => 1,
                   default => sub {
                       HTTP::Tiny->new;
                   }
               );

               sub store {
                   my( $self, $data ) = @_;

                   $self->ua->post( "http://.../store/$$", { body => $data } );
               }

               sub retrieve {
                   my( $self, $kid_id ) = @_;

                   $self->ua->get( "http://.../store/$kid_id" )->{content};
               }

           }

           my $fm = Parallel::ForkManager::Web->new(2);

           $fm->run_on_finish(sub{
               my $retrieved = $_[5];

               print "got ", $retrieved, "\n";
           });

           $fm->start_child(sub {
               return $_**2;
           }) for 1..3;

           $fm->wait_all_children;

   Example: have the child processes exit differently
           use Parallel::ForkManager;

           package Parallel::ForkManager::Child::PosixExit {
               use Moo::Role;
               with 'Parallel::ForkManager::Child';

               sub finish  { POSIX::_exit() };
           }

           my $fm = Parallel::ForkManager->new(
               max_proc   => 1,
               child_role => 'Parallel::ForkManager::Child::PosixExit'
           );

SECURITY

       Parallel::ForkManager  uses  temporary  files  when  a  child  process  returns information to its parent
       process. The filenames are based on the process of the parent and child processes,  so  they  are  fairly
       easy  to  guess.  So  if  security  is  a  concern  in  your environment, make sure the directory used by
       Parallel::ForkManager is restricted to the current user  only  (the  default  behavior  is  to  create  a
       directory, via File::Temp's "tempdir", which does that).

TROUBLESHOOTING

   PerlIO::gzip and Parallel::ForkManager do not play nice together
       If  you  are  using  PerlIO::gzip in your child processes, you may end up with garbled files. This is not
       really   P::FM's   fault,   but   rather   a   problem   between   PerlIO::gzip   and    "fork()"    (see
       <https://rt.cpan.org/Public/Bug/Display.html?id=114557>).

       Fortunately, it seems there is an easy way to fix the problem by adding the "unix" layer? I.e.,

           open(IN, '<:unix:gzip', ...

BUGS AND LIMITATIONS

       Do  not use Parallel::ForkManager in an environment where other child processes can affect the run of the
       main program; using this module is not recommended in an environment where fork()  /  wait()  is  already
       used.

       If you want to use more than one copies of the Parallel::ForkManager, then you have to make sure that all
       children processes are terminated, before you use the second object in the main program.

       You are free to use a new copy of Parallel::ForkManager in the child processes, although I don't think it
       makes sense.

CREDITS

         Michael Gang (bug report)
         Noah Robin <sitz@onastick.net> (documentation tweaks)
         Chuck Hirstius <chirstius@megapathdsl.net> (callback exit status, example)
         Grant Hopwood <hopwoodg@valero.com> (win32 port)
         Mark Southern <mark_southern@merck.com> (bugfix)
         Ken Clarke <www.perlprogrammer.net>  (datastructure retrieval)

AUTHORS

       •   dLux (Szabó, Balázs) <dlux@dlux.hu>

       •   Yanick Champoux <yanick@cpan.org>

       •   Gabor Szabo <gabor@szabgab.com>

COPYRIGHT AND LICENSE

       This software is copyright (c) 2018, 2016, 2015 by Balázs Szabó.

       This  is  free  software;  you  can  redistribute  it and/or modify it under the same terms as the Perl 5
       programming language system itself.

perl v5.28.0                                       2018-11-09                         Parallel::ForkManager(3pm)