我正在使用
Windows(草莓perl)中的一些长时间运行的perl脚本.
>第一个过程是父监控过程.它每24小时重新启动子进程,并将始终运行.
>第二个是子支付处理脚本.在关闭之前,此过程必须完成它正在执行的任何操作.
我的理解是在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和IO :: Select by 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’信号.这是因为线程也在内部模拟’kill’信号.
http://www.perlmonks.org/?node_id=557328
$SIG{'TERM'} = sub { threads->exit(); };
然后你的’主’可以:
$thr->kill('TERM')->detach();