Parallel PHP processes with PCNTL
1. Overview
In general, standard PHP does not provide parallel processes. There are some ways to do it such as using Process Control Extensions : Pthreads, PCNTL, or using message queue (see also https://labs.flinters.vn/technote/su-dung-beanstalkd-message-queue-system-voi-cakephp/). We chose PCNTL because it is simple, easy to implement and run with high effect.
PCNTL (Process Control – http://www.php.net/manual/en/book.pcntl.php) is an extension of PHP. It implements the Unix style of process creation, program execution, signal handling and process termination. It should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment. Note that this extension is not available on Windows platforms.
2. Installing and using PCNTL
Installing PCNTL
If Process Control support in your PHP is not enabled by default, you have to compile the CGI or CLI version of PHP with –enable-pcntl configuration option when compiling PHP to enable Process Control support.
In other way, I found a guide of installing PCNTL in Ubuntu without have to recompile entire PHP and done it successfully. You can follow it at http://www.crimulus.com/2010/07/30/howto-enable-pcntl-in-ubuntu-php-installations/.
Using PCNTL
With PCNTL extension, we use pcntl_fork() to create parallel processes.
When pcntl_fork() is called, it will return one of three values. If the return value is -1, the fork failed and there is no child process. This may be as a result of a lack of memory, or because the system limit on the number of user processes has been reached. If the return value is any number higher than 0, the current script is the parent that called pcntl_fork() and the return value is the process ID (PID) of the child that was forked. Finally, if the return value is 0, the current script is the child that was forked. So base on return value of pcntl_fork(), we can define what to do in each process (child or parent).
Example of create child process
function sigHandler($signo) { switch ($signo) { case SIGCHLD: // do something when a child exit break; default: break; } }
And add handler function with pcntl_signal() statement
pcntl_signal(SIGCHLD, ‘sigHandler’);