我的管道(文件句柄、套接字)(有时)会损坏。我可以使用以下代码重现它:
my $counter = 5;
alarm(1);
open(FH,"while(sleep 2); do date; done |") or die $!;
while (<FH>) { print; }
close(FH);
BEGIN {
$SIG{ALRM} = sub {
print "alarm!\n";
exit if --$counter == 0;
alarm(1);
};
}
这将产生:
alarm!
alarm!
Thu Feb 7 11:46:29 EST 2013
alarm!
alarm!
alarm!
如果我追踪这个过程,我会看到生成的 shell 收到一个 SIGPIPE。然而,Perl 进程愉快地继续着。我该如何解决这个问题?
最佳答案
问题是 <FH>
由于系统调用中断而返回 false。我不确定这是否是在 perl 中处理此问题的惯用方法(并且希望看到更好的答案),但以下似乎可行:
my $counter = 5;
alarm 1;
open my $fh, '-|', 'while(sleep 2); do date; done' or die $!;
loop:
while (<$fh>) { print; }
goto loop if $!{EINTR};
close $fh;
BEGIN {
$SIG{ALRM} = sub {
print "alarm!\n";
alarm 1;
exit if --$counter <= 0;
};
}
关于Perl:如何防止 SIGALRM 关闭管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14756747/