在Perl中使用waitpid和open3

时间:2014-07-14 08:47:52

标签: perl waitpid ipcopen3

如果open3调用的程序输出太大(超过65536),waitpid将永远运行。

use IPC::Open3;                                                                  
use POSIX ":sys_wait_h";                                                         

my ($stdin, $stdout, $stderr);                                                   
my $program = "perl -e 'print \"a\" x 65537'";                                   
my $args = [];                                                                   
my $pid = open3 $stdin, $stdout, $stderr, $program, @$args;

waitpid($pid, 0);

问题由WNOHANG解决:

my $kid;
while (1) {
    $kid = waitpid( $pid, WNOHANG );
    last unless $kid > 0;
}

但现在返回代码在$?是-1。它是waitpid的返回码。它可以用肮脏的黑客来解决:

my $open3_retcode;
my $kid;
while (1) {
    $open3_retcode = $?;
    $kid = waitpid( $pid, WNOHANG );
    last unless $kid > 0;
}

做这些事情的正确方法是什么?

UPD。似乎脏黑客并不总是有效。

1 个答案:

答案 0 :(得分:3)

如果你没有读取程序的输出(例如$ stdout和$ stderr),它会在一段时间后挂起,因为缓冲区已满。这将导致它永远不会返回。因此,正确的方法是读取程序发送给您的数据,直到您不再获取数据(eof)。然后你可以调用waitpid,它会成功。