【问题标题】:Perl signal handlers and WIndowsPerl 信号处理程序和 Windows
【发布时间】:2023-03-20 10:59:01
【问题描述】:

我在 Windows 上使用 Strawberry perl。我有一些运行 script.pl 的 GUI.pl 应用程序,它运行 some.exe。 perl 脚本充当 GUI 应用程序和 some.exe 之间的 STDIN/OUT/ERR 的代理。 问题是我无法杀死链 GUI.pl -> script.pl -> some.exe 中的 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;
}

【问题讨论】:

    标签: windows perl signals


    【解决方案1】:

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

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

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

    【讨论】:

    • 这个解释是错误的。 Deferred Signals 中记录的延迟过程不适用于 Windows 信号。
    • 我在这个解释中发现是IO操作期间无法处理信号。
    【解决方案2】:

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

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

    【讨论】:

    • kill TERM => $pidsends Ctrl-Break,可以是handled。 [我无法验证这一点,因为由于某种原因我无法处理任何信号。]
    猜你喜欢
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2017-04-02
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多