我需要在正在阻止io的脚本上超时。
令人惊讶的是,如果有打开的子流程管道,则exit会挂起:

#!/usr/bin/perl
(-f "foo") || die "file foo doesn't exist";
open(IN, "tail -f foo |");

$SIG{ALRM} = sub
{
    print "trying to exit...\n";
    exit 0;     # Hangs with above open() call
};
alarm 1;

while (1)
{
    sleep 5;   # Do stuff ...
}

在没有open调用的情况下,它可以工作,不幸的是,在这种情况下脚本需要它时,将其删除不是一个选择。

好像exit试图关闭文件句柄,这就是挂起的东西:
$SIG{ALRM} = sub
{
    print "trying to close...\n";
    close(IN);            # Hangs ...
    print "ok\n";
    exit 0;
};

我想从信号处理程序内部收割 child 不是很高兴...

有谁知道解决这个问题的好方法?

最佳答案

信号处理程序是红色鲱鱼,close会阻塞,无论如何:

open my $foo, "tail -f foo |" or die "Can't open process: $!";

close $foo;     # <--- will block

解决此问题的一种方法是先通过open捕获子进程的id,然后通过该 child 的kill捕获该子进程的ID:
my $subprocess = open my $foo, "tail -f foo |" or die "Can't open process: $!";

say "subprocess=$subprocess";

kill 'KILL', $subprocess;

close $foo;     # <--- happy now

关于linux - Perl:信号处理程序中的关闭子进程管道挂起?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34985690/

10-15 13:34