I did a fair amount of work with using pcntl_fork recently to create child processes for an import script. The two main benefits of forking are that the processes are contained (if one fails, they all do not fail) and the speed increase. Instead of running an import of 100 posts sequentially, it would instead run 10 child processes importing 10 posts each.
Anyway, to get to the point. I was testing the importer from the browser and finding really inconsistent and perplexing things happening.
pcntl_wait and pcntl_waitpid not working
The code was setup to store an array of the pids used, and to not allow more than 10 child processes at a time. So it was supposed to hit pcntl_wait or pcntl_waitpid and clear out the pid that had finished. The problem was that it never seemed to do that. I could see it was starting the processes and it was exiting them fine (ps -Hwfe from terminal verified there were no zombie processes).
My first thought after reading a bit about it was that perhaps the child process was finishing before the parent process had a chance to be informed the child process was starting. I tried adding sleep(10) into spots to try and delay the child process from finishing so quickly. Still didn’t work.
After realizing that pcntl_fork wasn’t supposed to be used from the browser when PHP was installed as an Apache module… I moved to using CLI to execute the script. I set it up so that I was using shell_exec() to execute the command after setting and uploading the import file. It worked great from CLI and I proceeded to bang my head into the wall a few times.
tldr; Use pcntl_fork, pcntl_wait, pcntl_waitpid in scripts run from CLI only… do not use them in the browser as that does not work as expected.