5

我正在尝试制作一个主 perl 脚本调用子 perl 脚本并通过管道进行交互。

我已经为大师编写了这段代码:

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

但是当我启动Master时,他只是在阅读孩子的反应时挂了。

知道我做错了什么,为什么?

4

2 回答 2

4

你正在遭受缓冲

在子进程开始附近说$|=1,以允许子进程打印而无需等待输出缓冲区填满。

于 2012-06-29T16:23:20.540 回答
0

附带说明一下,将 undef 传递给第三个参数(就像您一样)并不能满足您的要求。您需要使用 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;
于 2012-06-29T18:55:40.883 回答