I’m using proc::queue to manage a pile of child processes, and I fire them off like this:
if(Proc::Queue::running_now() < $kids)
{
logger("Starting another server process...");
my $newprocessid = Proc::Queue::run_back(\&serverprocess);
logger("New child process id: $newprocessid");
$childprocessids{$newprocessid} = 1;
}
So now I have a hash of the child process IDs that I can kill when the parent process is sent a kill SIGTERM.
But what if the child process is killed externally? The parent process knows to fire up another child to make up for the lost one, and the new child PID ends up in my hash, but how can the parent find out the PID of the child that died to remove it from the hash so I don’t try and kill it later?
I can set $SIG{CHLD} but I don’t see how to get the child PID to remove it from my hash.
You might place the parent and its children in their own process group and kill the whole family by sending a signal to the parent.
Depending on the nature of your problem, you may be willing to
killaway (Mr. McManus!) and live with the failures due to each attemptedkillon a child processes that is already dead.If the parent process does nothing but track the kids, a simple
waitpidloop is all you need.If you have other processing in the parent process, setting the
WNOHANGbit in the second argument towaitpidtells the system call not to block. This allows you to periodically reap zombie children and then go back to other processing.For demonstration purposes, say we start up a bunch of sleepy children.
Then to simulate kills from outside, we fork another child to pick off the rest of its siblings at random.
Now the loop from above reads the obituaries.
Double-check that no one made it out alive.
Output: