#!/usr/bin/perl use 5.010; use strict; use warnings; use POSIX ":sys_wait_h"; $|=1; # autoflush my %pids; sub reaper { $SIG{CHLD}=\&reaper; # This does not work, because you may get only one signal when # two or more processes exit at nearly the same time. This is due # to the way signals are implemented. #my $pid=wait(); #delete $pids{$pid}; my $pid; do { $pid=waitpid(-1, WNOHANG); delete $pids{$pid}; } while $pid>0; } $SIG{CHLD}=\&reaper; for (1..10) { my $pid=fork() // die "Can't fork: $!"; if ($pid) { # parent, remember PID $pids{$pid}++; say "Forked child $_, PID=$pid"; } else { # child $SIG{CHLD}='DEFAULT'; # maybe not needed, but doesn't hurt say "Child process $_"; sleep (5+rand(5)); exit 0; } } while (keys %pids) { say "Parent is working, ",scalar keys %pids," children still alive (PIDS ",join(', ',keys %pids),")..."; sleep 1; } say "all childs exited";