Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple open3 example not working

Tags:

perl

ipc

ipcopen3

I am trying to make a Master perl script calling children perl script and interacting through a pipe.

I have write this code for the master :

#!/usr/bin/env perl

use strict;
use warnings;

use IPC::Open3;

my @children;

for my $i ( 0 .. 4 ) {
    print "Master: " . $i . ", I summon you\n";

    $children[$i] = {};

    $children[$i]->{'pid'} = open3( my $CH_IN, my $CH_OUT, my $CH_ERR, 'perl child.pl -i ' . $i );

    $children[$i]->{'_STDIN'}  = $CH_IN;
    $children[$i]->{'_STDOUT'} = $CH_OUT;
    $children[$i]->{'_STDERR'} = $CH_ERR;

    my $line = readline $children[$i]->{'_STDOUT'};
    print $line ;

}

print "Master: Go fetch me the sacred crown\n";

for my $i ( 0 .. 4 ) {
    $children[$i]->{'_STDIN'}->write("fetch the sacred crown\n");
    my $line = readline $children[$i]->{'_STDIN'};
    print $line ;
}

print "Master: Thanks. Now die!!!\n";

for my $i ( 0 .. 4 ) {
    $children[$i]->{'_STDIN'}->write("die !!\n");
    my $line = readline $children[$i]->{'_STDIN'};
    print $line ;
}

And this one for the child :

#!/usr/bin/env perl

use Getopt::Long ;

my $cmdline_id ;

GetOptions ('i=s' => \$cmdline_id) ;

my $id = $cmdline_id ;

exit 1 if !defined $id ;

print "I am $id, and I am awaken\n" ;

while(<STDIN>) {
    print STDOUT $id . ': Master ask me to ' . $_ ;

    if ($_ =~ /exit/oi) {
        exit 0 ;
    }
}

But when I launch the Master he just hung while reading the response from the child.

Any idea about what I did wrong, and why ?

like image 888
Mayeu Avatar asked Oct 07 '22 09:10

Mayeu


1 Answers

You are suffering from buffering.

Say $|=1 near the beginning of the child process to allow the child to print without waiting for the output buffer to fill up.

like image 108
mob Avatar answered Oct 13 '22 11:10

mob