Tuesday, April 24, 2007

$SIG{CHLD} REAPER, system() or backticks concurrency

Why does system() or backticks command complete successfully but return -1 and "No child processes"?

Typically system() or backticks will wait() for their process to finish, and return status directly or via $?

Since our perlipc REAPER() function will perform a non-blocking waitpid() of all children finished, it is possible that some other child process AND the system() or backtick process could finish at or about the same time, while in "while (($child = waitpid(-1,&WNOHANG)) > 0)" loop. What will happen is the reaper will wait() on the PID of the finished child, as well as the finished system() or backtick operation, and the result will be unavilable for the system() or backtick call in it's typical fashion, and return -1; $! will return "No child processes".

This is an impossible scenario on a single processor machine, since there is no possibility in two processes actaully finishing at the same time.

The solution, turn off $SIG{CHLD} handing and REAPER() function for the block of code around your system() or backtick call, however DON'T use local(). $SIG{CHLD}='DEFAULT'. See my other post.

No comments: