perl forking and reaping on win32

For some mysterious reason, Windows has not yet implemented the POSIX fork() system call. I know, it’s strange, but I was always jealous of the numerous examples in the Camel Book on how easy it was to fork a child process and reap it when it was finished.

That is, until I came across Joe Johnston’s post about emulating the behavior in Win32 (yes, the post is a couple years old, but I just found it). Perl uses threads in the interpreter to mimic the POSIX behavior on Win32, and it seems to work pretty well.


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