【问题标题】:Perl: when doing 'open(A,"proc|")' make 'close(A)' return instantlyPerl:在执行 'open(A,"proc|")' 时使 'close(A)' 立即返回
【发布时间】:2011-09-11 01:35:10
【问题描述】:

如果我执行 'open(A,"proc|")',如何让 'close(A)' 立即返回, 即使“proc”还没有完成写入标准输出?

“man perlfunc”告诉我:

过早关闭管道的读取端(即在进程之前 在另一端写入它已关闭它)将导致 SIGPIPE 正在交付给作者。如果另一端无法处理 那,请务必在关闭管道之前读取所有数据。

但是有解决方法吗?具体例子:

$|=1; 
open(A,"curl -sN http://test.barrycarter.info/bc-slow-cgi.pl|"); 

while (<A>) { 
  print "THUNK: $_\n"; 
  if (/5$/) {last;} 
} 

print "LOOP EXIT\n"; 
close(A); 
print "A CLOSED\n"; 

bc-slow-cgi.pl 永远每秒打印一次 time():上面 代码打印“LOOP EXIT”,但从不打印“A CLOSED”。

【问题讨论】:

  • 你有什么版本的 perl 和 curl?您的代码在 perl 5.10.1 和 curl 7.21.3 上按预期工作。一些快速的谷歌搜索表明古代版本的 curl 中存在一些错误,导致它无法在 SIGPIPE 上退出
  • perl v5.10.0 和 curl 7.19.7。我打算升级,但我更喜欢 @ikegami 的解决方案,因为它也适用于非 curl 程序

标签: perl


【解决方案1】:

close 在由open -| 创建的句柄上等待子进程结束。在我看来,在您致电 close 后,下一次尝试写入时,孩子应该死于 PIPE 信号或错误,但如果您不想等那么久,您可以杀死孩子。

my $pid = open(...);

while (...) {
   ...
}

kill PIPE => $pid;
close(...);

PIPE 有点不正统,但在这里似乎很合适。随时发送TERM 或其他任何内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多