2012-06-29 6 views
5

Я пытаюсь сделать мастер-скрипт perl, вызывающий скрипт perl для детей и взаимодействующий через канал.Простой open3 пример не работает

меня написать этот код для мастера:

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

И это одно для ребенка:

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

Но когда я запускаю мастер, он просто висел, читая ответ от ребенка ,

Любая идея о том, что я сделал не так, и почему?

ответ

4

Вы - suffering from buffering.

Скажите $|=1 рядом с началом дочернего процесса, чтобы позволить ребенку печатать, не дожидаясь заполнения буфера вывода.

0

В качестве побочного примечания, передача undef для третьего arg (как и вы) не делает то, что вы хотите. Вам необходимо инициализировать переменную с помощью символа 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; 
Смежные вопросы