#!/usr/bin/perl use strict; use warnings; # POE checking/debug levels sub POE::Kernel::ASSERT_DEFAULT { 0 } # DATA, EVENTS, FILES, RETVALS, USAGE sub POE::Kernel::ASSERT_EVENTS { 1 } sub POE::Kernel::ASSERT_USAGE { 1 } sub POE::Session::ASSERT_STATES { 1 } use POE; use POSIX; my $num_kids = 8; my %kid_pids; main(); END { do_end(); } sub do_end { # FILL HERE exit(0); } sub main { # catch CTRL-C interrupt to tidy up cleanly $SIG{QUIT} = $SIG{INT} = $SIG{HUP} = \&do_end; POE::Session->create ( inline_states => { _start => sub { print "Starting\n"; $_[KERNEL]->sig('INT', 'signal_handler'); $_[KERNEL]->delay(reaper => 1 ); $_[KERNEL]->delay(spawner => 1 ); }, _stop => sub {}, signal_handler => sub { my ($kernel, $sig) = @_[KERNEL, ARG0]; print "caught SIG$sig\n"; do_end(); }, reaper => sub { $_[KERNEL]->delay(reaper => 1); while ( (my $pid = waitpid(-1, POSIX::WNOHANG)) > -1 ) { my $exit_status = $? / 256; delete $kid_pids{$pid}; print "child $pid died status $exit_status\n"; } }, spawner => sub { $_[KERNEL]->delay(spawner => 1); # start new kid if slot free if (scalar keys %kid_pids < $num_kids) { my $pid = start_child(); if ($pid > 0) { $kid_pids{$pid} = 1; print "child $pid started\n"; } } }, }, ); $poe_kernel->run(); } sub start_child { # FILL HERE return $pid; }