The pump
抛出一个die
出现错误时,或将其消息写入STDERR
if "所有利用活动完成后调用” 见之前ROUTINES http://search.cpan.org/%7Etoddr/IPC-Run-0.96/lib/IPC/Run.pm#ROUTINES部分和pump
本身。如果孩子退出,就会出现第二种情况。所以把pump
打电话进来eval
,并将警告转换为die
抓住这两种情况
if ($talk_to_child)
{
eval {
local $SIG{__WARN__} = sub { die "pump WARNING: @_" };
pump $harness;
};
if ($@) {
print $@;
$talk_to_child = 0;
};
}
# ... and eval {} for finish()
但这本身并不能解决问题:当父母试图给退出的孩子写信时,它会得到一个SIGPIPE
,这会彻底终止该进程。当子进程关闭流并且父进程尝试写入时,情况也是如此。所以还要安装一个信号处理程序SIGPIPE
$SIG{PIPE} = sub {
say "$_[0]: $!";
$talk_to_child = 0; # global
};
以便父母能够生存下来SIGPIPE
。考虑local https://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()- 将变化转化为全球性的%SIG https://perldoc.perl.org/perlvar.html#General-Variables通过做local $SIG{PIPE} = ...
相反,即使只是一般原则上也是一个好的做法。另一方面,全局处理可以突然终止您的信号(即使在处理程序可能决定退出的情况下)是很有意义的。
The eval
仍然需要即使$SIG{PIPE}
处理自pump
也扔。
它们一起处理了我提出的所有测试,几乎按原样进行。尽管如此,处理程序和中的一些处理eval
如果需要的话,需要区分感兴趣的案例。
如果这加起来太多,另一种方法是在每次调用之前进行检查。看这个帖子 https://stackoverflow.com/a/40662962/4653379对于单行检查(包含在子程序中):(1)子进程是否正在运行,使用result
,以及 (2) 是否“有开放的 I/O 通道或活动进程“, 使用pumpable
.
我认为你两者都想要,并且还加入了SIGPIPE
处理程序。那应该覆盖它。
我在这里无法更具体,因为问题没有提供具体细节。