in reply to Monitoring Child Process
So I would suggest:
You are not guaranteed to get a separate SIGCHLD for each child who exits! Basically interpret SIGCHLD to mean that one or more children have exited. Use a while loop to service everybody who is ready within the signal handler. There is not going to be a "false alarm", so I took that stuff out.sub REAPER { my $pid; while ($pid = waitpid(-1, WNOHANG) > 0) { print "Process $pid exited.\n"; push @dead_kids, $pid; } }
Also, to "reap" a child basically means to read its exit status from the process table. The function that does this read is waitpid(). When you have this in two places, somebody may get reaped and yet not go through the reaper. I recommend letting REAPER do all of the reaping and do not call waitpid() anywhere else. Maybe this issue is why you had the "false alarm" code, a race condition? Anyway, only reap in one place and you will not miss any and won't wind up in the signal handler with somebody mysteriously disappearing!
Update: temporarily don't have access to a unix box, so can't test, but here is a suggestion..
1. I see why you had the waitpid in the parent (so see if all children have finished). You need another test, perhaps, (@dead_kids < 10) with some wait delay. I think this test will be ok in Perl without further adieu. In C I would need to protect this critical section with some procmask() voodoo. But I think that due to the way Perl >=5.8 delivers deferred signals, that this is not necessary to prevent the REAPER and parent main program from tripping over each other.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Monitoring Child Process
by Anonymous Monk on Oct 19, 2011 at 19:59 UTC | |
by Marshall (Canon) on Oct 19, 2011 at 20:08 UTC | |
by Anonymous Monk on Oct 19, 2011 at 20:43 UTC | |
by Marshall (Canon) on Oct 20, 2011 at 01:28 UTC | |
by Anonymous Monk on Oct 20, 2011 at 04:00 UTC | |
|