megamic has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

Question regarding POE:Wheels, and they are are destroyed/reaped. Currently I use an approach where a message is sent to a Wheel, causing code in the child process to fall out of a loop and exit. This works fine but I get these annoying messages from the kernel:

!!! Child process PID:12793 reaped: 
!!! Child process PID:12795 reaped: 
!!! Child process PID:12791 reaped: 
!!! Child process PID:12794 reaped: 

All I am really after is a way to switch these messages off. Is there a better way to destroy a Wheel, or handle the reaping of a Wheel? I have tried registering the CHLD handler with the kernel, ie.

$_KERNEL->sig( CHLD => '_sig_child' );

While my _sig_child function is called, it doesn't suppress the kernel message.

Cheers

parsing XML is easy, said the data modeler to the programmer...you just look for an angle bracket and...

Replies are listed 'Best First'.
Re: destroying/reaping a POE::Wheel
by rcaputo (Chaplain) on Sep 04, 2008 at 04:18 UTC

    It sounds as if the program is exiting before all the child processes can be reaped. To avoid process leaks, POE will reap all outstanding attached child processes before exiting. The annoying warning is to let you know there's a problem. POE is often used in long-running daemons, where a silent process leak can lead to a mysteriously dead machine.

    So, what can you do? Try sig_child() rather than sig() to reap specific process IDs. For example:

    sub start_wheel { my $child = POE::Wheel::Run->new( ... ); $_[HEAP]{child} = $child; $_[KERNEL]->sig_child( $child->PID => "sig_child" ); }

    The sig_child() method asks that an event be dispatched when a specific PID is reaped. In this case, the PID associated with a particular POE::Wheel::Run instance. sig_child() is more convenient than the blanket sig() handler. Also, a session waiting for a specific PID will be kept alive until that process is reaped. If my guess is correct, this last feature should avert your program's warnings.

    sig_child() is documented in POE::Kernel, with the other POE::Kernel methods.

      Thanks, I tried two approaches based on your advice, and both worked!

      Putting a waitpid inside the sig_child handler worked as you suggested, however putting a 'do {} while (wait() > 0)' in the CloseEvent handler also did the trick. Im thinking the first method is better as it reaps earlier.

      Cheers