Don't ask to ask, just ask | |
PerlMonks |
Re: Monitoring Child Processby Marshall (Canon) |
on Oct 19, 2011 at 19:42 UTC ( [id://932483]=note: print w/replies, xml ) | Need Help?? |
First, the reaping code has a couple of flaws. (1) there are multiple places where you do a waitpid(), (2) the reaper routine can miss some SIGCHLD's., (3) no need to set $SIG{CHLD} within REAPER 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. 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.
In Section
Seekers of Perl Wisdom
|
|