Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How can you pass variables and output from child processes to parent in perl fork? and how can you make the parent to wait till all the children are finished before proceeding further.

Replies are listed 'Best First'.
Re: child processes in fork
by Frantz (Monk) on Apr 01, 2005 at 10:26 UTC
Re: child processes in fork
by Zaxo (Archbishop) on Apr 01, 2005 at 13:45 UTC

    A third way is to call pipe before fork to set up a reader and writer handle. You'll want to set the writer to autoflush, and to close the unwanted end of the pipe in each process.

    That is low level, so is very flexible and powerful. Writing C in Perl is not always a bad thing.

    Here's how to set up the child as a coprocess, taking STDIN from the parent, and writing back STDOUT to the parent. That needs two pipes, one each direction.

    my ($reader,$writer,$cpid); { pipe $reader, local *STDOUT or die $!; pipe local(*STDIN), $writer or die $!; $cpid = fork; defined $cpid or die $!; last if $cpid; # child close $reader or die $!; close $writer or die $!; $| = 1; exec '/path/to/foo', @foo_args; die 'Failed to launch foo: ', $!; } # parent select((select($writer), $| = 1)[0]); # see 'perldoc -f select' # builtin 4-arg select or IO::Select may be handy here # . . . waitpid $cpid;
    Untested. Will fail if foo is naive about file descriptors for STDIN and STDOUT.

    After Compline,
    Zaxo

Re: child processes in fork
by cog (Parson) on Apr 01, 2005 at 10:38 UTC
    wait till all the children are finished

    Use wait (if it returns -1, then you have no childs left).

Re: child processes in fork
by Random_Walk (Prior) on Apr 01, 2005 at 13:34 UTC

    If you wish to gather its output and wait for the child there are two simple options. The first runs the child to completion then gets its output

    perl -le '$result=`echo "hello world"`;print $result; print "OK"'
    The second starts the child and reads its output line at a time untill it is done.
    perl -le 'open CHLD, "ls -l |";while(<CHLD>){chomp; print "got: $_"} p +rint "OK"'

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!