OH gurus of perl, I seek thy wisdom........

I have a script that I am working with that starts a few child processes and keeps track of them for reaping. Most of the code for this was taken from the perl cookbook, and then I tweaked it a bit. So this is what I have:

Main program:
:::::::::::::: mxMSsmtp ::::::::::::::
#!/usr/bin/perl use mxMSsmtp::Config; use mxMSsmtp::Run; use Getopt::Std; use strict; my %opts; my $cfg = undef; my $pid; getopts('c:D', \%opts); $cfg = $opts{c} if $opts{c}; my $vars = mxMSsmtp::Config::get($cfg) or die "Problem getting config +file\n"; if ($opts{D}) { run mxMSsmtp::Run($vars) unless $pid = fork; } else { run mxMSsmtp::Run($vars); } exit;
and the processing mod:
:::::::::::::: Run.pm ::::::::::::::
package mxMSsmtp::Run; use Symbol; use POSIX; use strict; my %children = (); my $children = 0; sub _REAPER { $SIG{CHLD} = \&_REAPER; my $pid = wait; $children--; delete $children{$pid}; } sub _KILLER { local($SIG{CHLD}) = 'IGNORE'; kill 'INT' => keys %children; exit; } sub run { my ($me, $vars) = @_; my $preFork = $vars->{preFork}; for (1 .. $preFork) { _startCHLD($vars); } $SIG{CHLD} = \&_REAPER; $SIG{INT} = \&_KILLER; while (1) { sleep; for (my $i = $children; $i < $preFork; $i++) { _startCHLD($vars); } } } sub _startCHLD { my ($vars) = @_; my $pid; my $sigset; $sigset = POSIX::SigSet->new(SIGINT); sigprocmask(SIG_BLOCK, $sigset) or die $!; die $! unless defined ($pid = fork); if ($pid) { # Parent process sigprocmask(SIG_UNBLOCK, $sigset) or die $!; $children{$pid} = 1; $children++; return; } else { # Child Process $SIG{INT} = 'DEFAULT'; sigprocmask(SIG_UNBLOCK, $sigset) or die $!; for (my $i = 0; $i < $vars->{maxClients}; $i++) { print "$i\n"; sleep(10); } exit; } } 1;

So, on a whole this works exactly the way it is supposed to, though it causes some of the child procs to go <defunct> after the first run through of max clients. I think the problem is with the reaping sub, and when child procs die at the same time. If two child procs die at the same time and the main program tries to reap them, could there be a problem with the variables ($children and %children) being stepped on. Granted that the program is going to be a SMTP listener (which I already have the frame work writen), so the actual possibility of child procs dieing at the same time would be rare. So to my questions, are my thoughts on the whole thing correct, and if so is there a way to lock/block during child reaping????

Thanx

In reply to Reaping Child procs causing <defunct>???? by slydog

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.