The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

IO::Lambda::Fork - wait for blocking code using coprocesses

DESCRIPTION

The module implements a lambda wrapper that allows to asynchronously wait for blocking code. The wrapping is done so that the code is executed in another process's context. IO::Lambda::Fork provides a twofold interface: First, it the module can create lambdas that wait for forked child processes. Second, it also provides an easier way for simple communication between parent and child processes.

Contrary to the usual interaction between a parent and a forked child process, this module doesn't hijack the child's stdin and stdout, but uses a shared socket between them. That socket, in turn, can be retrieved by the caller and used for its own needs.

SYNOPSIS

    use IO::Lambda qw(:lambda);
    use IO::Lambda::Fork qw(forked);

    lambda {
        context 0.1, forked {
              select(undef,undef,undef,0.8);
              return "hello!";
        };
        any_tail {
            if ( @_) {
                print "done: ", $_[0]-> peek, "\n";
            } else {
                print "not yet\n";
                again;
            }
        };
    }-> wait;

API

new_process($code, $pass_socket, @param) -> ( $pid, $socket | undef, $error )

Forks a process, and sets up a read-write socket between the parent and the child. On success, returns the child's pid and the socket, where the latter is passed to $code. On failure, returns undef and $!.

This function doesn't create a lambda, and doesn't make any preparation neither for waiting for the child process, nor for reaping its status. It is therefore important to wait for the child process, to avoid zombie processes. It can be done either synchronously:

    my ( $pid, $reader) = new_process {
        my $writer = shift;
        print $writer, "Hello world!\n";
    };
    print while <$reader>;
    close($reader);
    waitpid($pid, 0);

or asynchronously, using lambdas:

    use IO::Lambda::Socket qw(pid new_pid);
    ...
    lambda { context $pid; &pid() }-> wait;
    # or
    new_pid($pid)-> wait;
process($code) :: () -> ($? | undef)

Creates a simple lambda that forks a process and executes $code inside it. The lambda returns the child exit code.

new_forked($code) :: () -> ( $?, ( 1, @results | undef, $error))

Creates a lambda that waits for $code in a sub-process to be executed, and returns its result back to the parent. Returns also the process exitcode, $code eval success flag, and results (or an error string).

forked($code) :: () -> (@results | $error)

A simple wrapper over new_forked, that returns either $code results or an error string.

BUGS

Doesn't work on Win32, because relies on $SIG{CHLD} which is not getting delivered (on 5.10.0 at least). However, since Win32 doesn't have forks anyway, Perl emulates them with threads. Use IO::Lambda::Thread instead when running on windows.

AUTHOR

Dmitry Karasik, <dmitry@karasik.eu.org>.