Under my setup (FreeBSD 6.2-RELEASE / PHP 5.2.4 CLI) I've noticed that when a child exits the SIGCHLD handler in the parent is not always invoked. It seems to happen when two children exit near simultaneously.
In this instance the child prints "EXIT" and the parent prints "SIGCHLD received":
- EXIT
- SIGCHLD received
This works as expected, but now look what happens when three exit in quick succession:
- EXIT
- EXIT
- EXIT
- SIGCHLD received
- SIGCHLD received
Because of this quirk any code which tries to limit the maximum number of children by incrementing on fork and decrementing on SIGCHLD will eventually end up with a single child (or no further forks), since the "active children" count is always above the maximum. I've noticed similar behaviour with using decrement after pcntl_wait(). Hopefully there's a workaround for this.