Perl信号处理程序和WIndows

时间:2015-10-19 13:17:50

标签: windows perl signals

我在Windows上使用Strawberry perl。我有一些GUI.pl应用程序运行 script.pl 运行 some.exe 。 perl脚本用作GUI应用程序和some.exe之间的STDIN / OUT / ERR的代理。 问题是我无法杀死链GUI.pl中的some.exe进程 - > script.pl - > some.exe。

GUI.pl 将TERM发送到 script.pl

# GUI.pl
my $pid = open my $cmd, '-|', 'script.pl';
sleep 1;
kill 'TERM', $pid;

script.pl 捕获'TERM'并试图杀死 some.exe

# script.pl
$SIG{TERM} = \&handler;
my $pid = open my $cmd, '-|', 'some.exe';
sub handler {
    kill 'TERM', $pid;
}

使用此方案,some.exe的进程将继续执行。我已经学到了很多关于信号的知识,但仍然不明白如何解决这个问题。

提前感谢。

正在使用threads的其中一个解决方案:

# script.pl
use threads;
use threads::shared;

$SIG{BREAK} = \&handler;

my $pid :shared;

async {
    $pid = open my $cmd, '-|', 'some.exe'
}->detach;

# 1 second for blocking opcode. After sleep handler will be applied
sleep 1;     

sub handler {
    kill 'TERM', $pid;
}

2 个答案:

答案 0 :(得分:0)

我会警惕在Windows上使用'kill'信号,因为它们是POSIX的东西。 http://perldoc.perl.org/functions/kill.html

但我认为这里的问题可能是因为Deferred Signals。特别是如果您向进程发送信号,解释器将一直等到处理它“安全”。在“some.exe”中间不太可能。

以这种方式使用kill信号并不是一种特别好的IPC形式。有关有用的讨论,请参阅perlmonks: Signals Vs. Windows

答案 1 :(得分:0)

Windows上的信号非常特殊。 INTQUIT信号可能比TERM更好运。我对Perl和Windows如何处理信号的广泛研究进行了总结here

TL; DR:在Windows上,TERM可以终止Windows中的进程,但无法处理。可以处理INTQUIT,其默认行为是终止进程。如果你使用Windows伪进程(如果你在Windows中调用fork就是这样),那么事情就会变得更加复杂。