2012-06-29 24 views
5

Estoy tratando de hacer una secuencia de comandos maestra de perl que llame al script de perl de los niños e interactúe a través de un conducto.Ejemplo simple de open3 que no funciona

que tienen escribir el código para el maestro:

#!/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 ; 
} 

Y esto es para el niño:

#!/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 ; 
    } 
} 

Pero cuando inicio el Maestro que sólo pasamos al leer la respuesta del niño .

¿Alguna idea sobre lo que hice mal y por qué?

Respuesta

4

Usted es suffering from buffering.

Diga $|=1 cerca del comienzo del proceso hijo para permitir que el niño imprima sin esperar a que se llene el búfer de salida.

0

Como nota al margen, pasar undef para la tercera arg (como lo es) no hace lo que quiere. Debe inicializar la variable usando Symbol gensym.

use Symbol qw(gensym); 

my %child; 
$child{pid} = open3(
    $child{'_STDIN' } = gensym, 
    $child{'_STDOUT'} = gensym, 
    $child{'_STDERR'} = gensym, 
    'perl', 'child.pl', '-i' => $i 
); 

$children[$i] = \%child;