2012-06-29 12 views
5

Ich versuche, ein Master-Perl-Skript aufrufen Kinder perl-Skript und Interaktion durch eine Pipe.Einfach open3 Beispiel funktioniert nicht

Ich habe diesen Code für den Master schreiben:

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

Und diese für das Kind:

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

Aber wenn ich den Meister starten hängte er nur während der Antwort von dem Kind lesen .

Irgendeine Idee darüber, was ich falsch gemacht habe, und warum?

Antwort

4

Sie sind suffering from buffering.

Sagen Sie $|=1 in der Nähe des Beginns des untergeordneten Prozesses, damit das Kind drucken kann, ohne auf das Auffüllen des Ausgabepuffers zu warten.

0

Als eine Randnotiz, Übergeben undef für den dritten arg (wie Sie sind) nicht tun, was Sie wollen. Sie müssen die Variable mit Symbols gensym initialisieren.

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; 
Verwandte Themen