Gordolio
Gordolio

Reputation: 1997

perl Win32 Signal Handling between perl processes

I have a couple long running perl scripts in windows (strawberry perl) that I'm working on.

  1. The first process is a parent monitoring process. It restarts the child process every 24 hours and will be always running.
  2. The second is the child payment processing script. It is imperative that this process completes whatever it's doing before being shutdown.

It's my understanding that signal handling doesn't work in perl on win32 and that it shouldn't be relied on. Is there some other way that I can handle a signal? Win32::Process::Kill seems to kill the process without letting it safely shut down.

This is the signal handling that I've tried...

#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);

The only other thing I can think of is to open a socket between the two processes and write messages across the socket. But there must be something easier. Anyone know of any module that can do this?

Update

I've started working on creating a "signal" mechanism via IO::Socket::INET and IO::Select by opening a socket. This appears to work and I'm thinking of writing a module that is compatible with AnyEvent. But I'm still interested in an implementation that doesn't require opening a listening port and that doesn't require a server/client relationship. Is it possible to do this by subscribing to and firing custom events in windows?

Upvotes: 5

Views: 553

Answers (2)

Curufin
Curufin

Reputation: 21

With ActiveState Perl I use windows native events through the Win32::Event module.

This way you don't need to implement anything fancy and you can even have your script interract with native applications. I use this module in many applications.

Since it is part of Win32::IPC, which uses native code, it may not be available for Strawberry Perl. If that is the case you could try compiling it from the CPAN sources. It might be worth a try if you have lots of Windows perl-based software.

Upvotes: 0

Sobrique
Sobrique

Reputation: 53498

Hmm, an interesting question. One thing I'd be wondering - how feasible is it to rewrite your code to thread?

When faced with a similar problem I found encapsulating the 'child' process as a thread meant I could better 'manage' it from the parent.

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 ); 
}

But because you've got the IPCs from threading - you've got Thread::Queue, threads::shared, Thread::Semaphore and - I'm at least fairly sure you can send pseudo 'kill' signals within the script. This is because threads emulates 'kill' signals internally too.

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

Add to your thread:

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

And then then your 'main' can:

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

Upvotes: 0

Related Questions