Perl:如何防止SIGALRM关闭管道?

时间:2013-02-07 17:02:49

标签: perl signals alarm filehandle

我的管道(文件句柄,套接字)中断(有时)。我可以使用以下代码重现它:

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进程很快就会继续。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

问题是由于系统调用中断,<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;
    };
}