perl 进程之间的 perl Win32 信号处理

Posted

技术标签:

【中文标题】perl 进程之间的 perl Win32 信号处理【英文标题】:perl Win32 Signal Handling between perl processes 【发布时间】:2014-04-05 15:05:30 【问题描述】:

我正在处理的 Windows(草莓 perl)中有几个长时间运行的 perl 脚本。

    第一个进程是父监控进程。它每 24 小时重新启动一次子进程,并将始终运行。 第二个是子支付处理脚本。此过程必须在关闭之前完成它正在执行的所有操作。

据我了解,win32 上 perl 中的信号处理 doesn't work 不应依赖它。还有其他方法可以处理信号吗? Win32::Process::Kill 似乎在没有让它安全关闭的情况下杀死了进程。

这是我尝试过的信号处理...

#Child
my $interrupted = 0;
$SIGINT = 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::INETIO::Select 通过opening a socket 创建“信号”机制。这似乎可行,我正在考虑编写一个与AnyEvent 兼容的模块。但是我仍然对不需要打开侦听端口并且不需要服务器/客户端关系的实现感兴趣。是否可以通过在 Windows 中订阅和触发自定义事件来做到这一点?

【问题讨论】:

【参考方案1】:

嗯,一个有趣的问题。我想知道一件事 - 将代码重写为线程有多可行?

当遇到类似问题时,我发现将“子”进程封装为线程意味着我可以更好地从父进程“管理”它。

例如:

#!/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::Queuethreads::sharedThread::Semaphore 和 - 我至少相当确定你可以在脚本中发送伪“kill”信号。这是因为线程也在内部模拟“kill”信号。

http://www.perlmonks.org/?node_id=557328

添加到您的主题:

$SIG'TERM' = sub  threads->exit(); ;

然后你的“主要”可以:

$thr->kill('TERM')->detach();

【讨论】:

【参考方案2】:

使用 ActiveState Perl 我通过 Win32::Event 模块使用 Windows 原生事件。

这样您就不需要实现任何花哨的东西,甚至可以让您的脚本与本机应用程序交互。 我在很多应用程序中都使用了这个模块。

由于它是使用本机代码的Win32::IPC 的一部分,它可能不适用于Strawberry Perl。如果是这种情况,您可以尝试从 CPAN 源编译它。如果您有很多基于 perl 的 Windows 软件,可能值得一试。

【讨论】:

以上是关于perl 进程之间的 perl Win32 信号处理的主要内容,如果未能解决你的问题,请参考以下文章

Perl:关闭信号处理程序中的子进程管道挂起?

对 system() 的调用不会在我的 Windows 进程之间创建父子关系

如何从 Perl 完全改变 Win32 标题栏的外观?

perl win32 api 如何遍历已打开窗口,获得每个窗口的标题内容

如何使用 Perl 中的 Win32::LongPath 模块来操作长路径名?

Perl Win32::OLE 生成访问数据库