2012-06-29 28 views
5

Tôi đang cố gắng thực hiện một kịch bản lệnh perl chính gọi cho trẻ em kịch bản perl và tương tác thông qua một đường ống.Ví dụ open3 đơn giản không hoạt động

Tôi có viết mã này cho các bậc thầy:

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

Và cái này cho đứa trẻ:

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

Nhưng khi tôi khởi động Master ông chỉ treo trong khi đọc các phản hồi từ các con .

Bất kỳ ý tưởng nào về những gì tôi đã làm sai và tại sao?

Trả lời

4

Bạn đang suffering from buffering.

Nói $|=1 gần đầu quá trình con để cho phép trẻ in mà không cần chờ bộ đệm đầu ra lấp đầy.

0

Là một lưu ý phụ, chuyển undef cho arg thứ ba (như bạn) không làm những gì bạn muốn. Bạn cần khởi tạo biến bằng cách sử dụng 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; 
Các vấn đề liên quan