Parallel-ForkManager

 view release on metacpan or  search on metacpan

README.mkdn  view on Meta::CPAN

- 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.

    ```perl
    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



( run in 0.761 second using v1.01-cache-2.11-cpan-39bf76dae61 )