[advertisement]

Interested in putting your ad here?

Blog Entry

7th May 2004
Send to twitter Send to Facebook

Here's the deal: you're on win32, you need to fork() and you're using Perl. Since version 5.6, win32 Perl has had fork() emulation. That's good. It's emulation (accomplished at the interpreter level with threading), so standard Unix tricks like using a signal handler to reap children and control the number of child process don't work. That's bad.

Here then is my Win32 Perl recipe for the week: Limiting forked child "processes" under Win32 Perl (versions 5.6 and higher).

use strict;
use POSIX ":sys_wait_h";
use constant MAX_KIDS => 4;
 
my (%children, $quit) = ((), 0);
print "[$$] Entering main loop\n";
while (!$quit) {
  reap(\%children);
  
  if ((keys %children) <= MAX_KIDS) {
    print "[$$] Forking child $_\n";
    if (my $pid = fork()) {
      $children{$pid} = 1;
    } else {
      do_child();
      exit;
    }
  } else {
    $quit = 1;
  }
 
  sleep(1);
}
 
# reap existing kids
while (keys %children) {
  reap(\%children);
  sleep(1);
}
 
print "All children reaped\n";
 
#--------
# sub 
#--------
sub reap {
  my ($kids) = @_;
  for (keys %{$kids}) {
    print "[$$]child '$_' reapable?\n";
    next if waitpid($_,WNOHANG()) != -1;
    print "[$$]child '$_' reaped\n";
    delete $kids->{$_};
  }
}
  
sub do_child {
  sleep(1) for 0..10;
  print "[$$] done\n";
}

Note that you can do other work in the main reaping loop.

The main loop is really the service state loop for a Win32 service. Also note that reaping the child "processes" isn't strictly necessary. Not only are the children not real processes (they are interpreter threads), but also no zombies can be created if the parent process exits without calling wait(). All child "processes" will be terminated with the parent. So you've got that going for you.

See David Roth's web site, books or articles for more excellent details on the devilish art of creating Win32 services with Perl.

[Original use.perl.org post and comments. Minor cleanup on 11/30/2007.]

Threads in Threads!
:: 30th Nov 2007 - 10:11
:: Stuart Davidson
Hey Joe, I know this is a bit of thread-o-mancy, but this technique works and has helped me out with an issue whereby the 'processes' were being removed but a thread in the parent process was not. (meaning only 64 children before the thing fell on it's face). Good work!

Blog archives

+ About this blog