我正在处理的 Windows(草莓 perl)中有几个长时间运行的 perl 脚本。
据我了解,信号处理doesn't work在 win32 上的 perl 中,不应该依赖它。还有其他方法可以处理信号吗?
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
创建一个“信号”机制。和 IO::Select
由 opening a socket .这似乎可行,我正在考虑编写一个与 AnyEvent 兼容的模块.但是我仍然对不需要打开监听端口并且不需要服务器/客户端关系的实现感兴趣。是否可以通过在 Windows 中订阅和触发自定义事件来做到这一点?
最佳答案
嗯,一个有趣的问题。我想知道的一件事 - 将代码重写为线程有多可行?
当遇到类似的问题时,我发现将“子”进程封装为线程意味着我可以更好地从父进程“管理”它。
例如。:
#!/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();
关于perl 进程之间的 perl Win32 信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22165867/