我在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;
}
答案 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上的信号非常特殊。 INT
或QUIT
信号可能比TERM
更好运。我对Perl和Windows如何处理信号的广泛研究进行了总结here。
TL; DR:在Windows上,TERM
可以终止Windows中的进程,但无法处理。可以处理INT
和QUIT
,其默认行为是终止进程。如果你使用Windows伪进程(如果你在Windows中调用fork
就是这样),那么事情就会变得更加复杂。