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

Gor*_*lio 5 perl winapi

我正在使用Windows(草莓perl)中的一些长时间运行的perl脚本.

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

我的理解是,信号处理在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);
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一另一件事是在两个进程之间打开一个套接字并在套接字上写消息.但必须有一些更容易的事情.有人知道任何可以做到这一点的模块吗?

更新

我已经开始创造一个"工作信号通过"机制IO::Socket::INET,并IO::Select通过打开一个插座.这似乎工作,我正在考虑编写一个与AnyEvent兼容的模块.但我仍然对不需要打开侦听端口且不需要服务器/客户端关系的实现感兴趣.是否可以通过在Windows中订阅和触发自定义事件来实现此目的?

Sob*_*que 0

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

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

例如:

#!/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 ); 
}
Run Code Online (Sandbox Code Playgroud)

但是因为您已经从线程中获得了 IPC - 您已经获得了Thread::Queue、和 - 我至少相当确定您可以在脚本中发送伪“kill”信号。这是因为线程也在内部模拟“kill”信号。threads::sharedThread::Semaphore

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

添加到您的线程:

$SIG{'TERM'} = sub { threads->exit(); };
Run Code Online (Sandbox Code Playgroud)

然后你的“主要”可以:

$thr->kill('TERM')->detach();
Run Code Online (Sandbox Code Playgroud)