Here's a stripped down version of the driver program:
And here's the output from one run, before it freezes:#!/bin/env perl use 5.010; use warnings; use strict; use Carp; use File::Basename; use IO::Socket; use IO::Select; use IO::File; use POSIX qw{WNOHANG setsid}; use POSIX qw{SIGHUP SIGTERM SIGUSR1}; my $sigset = POSIX::SigSet->new(); # SIGCHLD (17) child-process ended # my $CHLDaction = POSIX::SigAction->new( 'sigCHLD_handler', $sigset, &POSIX::SA_NODE +FER ); POSIX::sigaction( &POSIX::SIGCHLD, $CHLDaction ); sub sigCHLD_handler { say "Enter sigCHLD handler"; } say "Perl version: $^V"; my $active_readers = 0; my $current_reader_limit = 10; while (1) { if ($active_readers < $current_reader_limit) { # Launch enough new readers to bring us up to the current limi +t while ($active_readers < $current_reader_limit) { ++$active_readers; my $service_pid; if ( !defined( $service_pid = fork ) ) { say "Couldn't fork. Exit."; exit; } # CHILD process # elsif ( 0 == $service_pid ) { my $command = "echo Hello from child $active_readers " + . 'pid $$'; exec $command; } # PARENT process say "Spawned child $active_readers pid $service_pid" } } sleep; say "Out of sleep, begin reaping"; while ( ( my $kid = waitpid( -1, WNOHANG ) ) > 0 ) { --$active_readers; say "Reaping child process $kid, active readers now $active_re +aders"; } say "Finished reaping"; }
I do nothing in the signal handler that would cause a data race; it's there only to cause sleep to wake up.$ tom_strip Perl version: v5.16.2 Spawned child 1 pid 18734 Spawned child 2 pid 18735 Spawned child 3 pid 18736 Spawned child 4 pid 18737 Spawned child 5 pid 18738 Spawned child 6 pid 18739 Spawned child 7 pid 18740 Spawned child 8 pid 18741 Spawned child 9 pid 18742 Spawned child 10 pid 18743 Hello from child 1 pid 18734 Enter sigCHLD handler Out of sleep, begin reaping Hello from child 2 pid 18735 Reaping child process 18734, active readers now 9 Finished reaping Hello from child 3 pid 18736 Enter sigCHLD handler Hello from child 4 pid 18737 Enter sigCHLD handler Hello from child 5 pid 18738 Enter sigCHLD handler Hello from child 6 pid 18739 Enter sigCHLD handler Enter sigCHLD handler Hello from child 7 pid 18740 Enter sigCHLD handler Hello from child 9 pid 18742 Hello from child 8 pid 18741 Hello from child 10 pid 18743 Hello from child 10 pid 18748
In every case where I've looked, there are no children processes remaining, and only the driver program remains.
If someone could explain what's going wrong, and what the right way to accomplish this is, I'd appreciate it.
In reply to Managing the fork/execing and reaping of child processes by ibm1620
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |