my @child_info; foreach my $params (@params_for_children) { my $child = Foo::Child->new( params => $params ); $child->spawn(); push @child_info, $child; } while ( my $pid = wait() ) { last if $pid = -1; my $exit_status = $?; my ($poor_dead_child) = grep { $_->{pid} == $pid } @child_info; $poor_dead_child->fyi_you_died(); $poor_dead_child->spawn(); } package Foo::Child; sub new { my $class = shift; my $self = { @_ }; return bless $self, $class; } sub DESTROY { kill 'TERM' => shift->{pid} } sub fyi_you_died { shift->{death_toll}++ } sub spawn { my $self = shift; my $pid = fork; die "Can't fork: $!" if ! defined $pid; if ( $pid ) { $self->{pid} = $pid; return; } else { sleep ... if $self->{death_toll} > ...; do_child_stuff( $self->{params} ); die; } }