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

标签 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 进程愉快地继续着。我该如何解决这个问题?

最佳答案

问题是 <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/

相关文章:

java - 将 Perl 转换为 Java

c++ - 信号/槽基类多继承

javascript - Chrome API 警报在页面刷新后停止

Android 模拟器闹钟崩溃

perl - 如何在 perl 中编码邮件主题?

html - 从 Perl 中的富文本编辑器解析 HTML 的最佳方法是什么?

perl - Perl 模块 autodie 和 Fatal 有什么区别?

c - 如何正确处理C中的信号

c++ - sig_atomic_t 和 std::atomic<> 可以互换吗?

Android:从 onReceive 方法设置新的闹钟