我正在使用Windows(草莓perl)中的一些长时间运行的perl脚本。
我理解在win32上perl中的信号处理doesn't work并且不应该依赖它。还有其他方法可以处理信号吗? Win32::Process::Kill
似乎在不让它安全关闭的情况下杀死了这个过程。
这是我尝试过的信号处理......
#Child
my $interrupted = 0;
$SIG{INT} = sub{$interrupted = 1;};
while(!$interrupted){
#keep doing your thing, man
}
#Parent
my $pid = open2(\*CHLD_OUT,\*CHLD_IN,'C:\\strawberry\\perl\\bin\\perl.exe','process.pl');
kill INT=>$pid;
waitpid($pid,0);
我唯一能想到的是在两个进程之间打开一个套接字并在套接字上写消息。但必须有一些更容易的事情。有人知道任何可以做到这一点的模块吗?
更新
我已经开始通过IO::Socket::INET
创建“信号”机制,opening a socket创建IO::Select
。这似乎有效,我正在考虑编写一个与AnyEvent兼容的模块。但我仍然对不需要打开侦听端口且不需要服务器/客户端关系的实现感兴趣。是否可以通过在Windows中订阅和触发自定义事件来实现此目的?
答案 0 :(得分:0)
当遇到类似问题时,我发现将'子'进程封装为线程意味着我可以更好地从父进程“管理”它。
e.g:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use threads::shared;
my $interrupted : shared;
sub child {
while ( not $interrupted ) {
#loop;
}
}
#main process
while ( 1 ) {
$interrupted = 0;
my $child = threads -> create ( \&child );
sleep 60;
$interrupted = 1;
$child -> join();
sleep ( 3600 );
}
但是因为你有来自线程的IPC - 你有Thread::Queue
,threads::shared
,Thread::Semaphore
而且 - 我至少相当确定你可以发送伪'杀'脚本中的信号。这是因为线程也在内部模拟'kill'信号。
http://www.perlmonks.org/?node_id=557328
添加到您的主题:
$SIG{'TERM'} = sub { threads->exit(); };
然后你的'主'可以:
$thr->kill('TERM')->detach();
答案 1 :(得分:0)
使用 ActiveState Perl 我通过Win32::Event模块使用Windows本机事件。
这样您就不需要实现任何花哨的东西,甚至可以让脚本与本机应用程序相互作用。 我在许多应用程序中使用此模块。
由于它是使用本机代码的Win32::IPC的一部分,因此它可能不适用于 Strawberry Perl 。如果是这种情况,您可以尝试从 CPAN 源编译它。如果你有很多基于Windows perl的软件,那么值得一试。