As we all know, PHP is executed by a single process, and THE multi-concurrent processing of PHP mainly depends on the multiple processes of the server or PHP-FPM and their reuse. However, the realization of multi-process in PHP is also of great significance, especially when processing a large amount of data in the background Cli mode or running the daemon of the background DEMON, the advantages of multi-process need not be mentioned.

To implement multi-process PHP, we need two extensions, PCNTL and POSIX, which are not described here.

In PHP we use pcntl_fork() to create multiple processes (in C programming for the *NIX system, an existing process calls fork to create a new process). When fork, the new process becomes the child and the original process becomes the parent. The child process has a copy of the parent process. Note here:

• Child processes share program body segments with parent processes

• The child process owns a copy of the parent process’s data space and heap and stack. Note that the copy is not shared

• The parent and child processes continue executing the program code after fork

• After fork, it is not clear whether the parent or child executes first, depending on system scheduling (depending on beliefs)


It is said that the child has a copy of the parent’s data space as well as a heap and stack. In fact, in most implementations it is not a true full copy. Copy On Write (COW) is used to save storage space. In short, if neither parent nor child processes modify the data, heap, or stack, then parent and child processes temporarily share the same data, heap, or stack. Replication occurs only when the parent or child processes attempt to make changes to the data, heap, or stack. This is called write on copy.

After calling pCNTL_fork (), the function returns two values. Returns the child’s process ID in the parent process and the number 0 in the child itself. Since multiple processes do not run properly in Apache or FPM, it is important to run your code in PHP CLI.


Creating a child process

Creating a PHP child is the beginning of a multi-process process, and we need the pcntl_fork() function;


The fork function is explained

Pcntl_fork () – Generates branches (child processes) at the current location of the current process. When this function creates a new child, the child inherits the parent’s current context and executes from pcntl_fork(), just as the parent does, except that the return value of pcntl_fork() is different. Assign parent and child processes to do different logical processing.

If the pCNtl_fork () function is successfully executed, the parent process will return the process ID (PID) of the child process. Because the pid of the system’s initial process init is 1, the pid of subsequent processes will be larger than this process. Pcntl_fork () returns a value greater than 1 to confirm that the current process is the parent; In the child process, this function returns a fixed value of 0. We can also determine the child process by determining that pcntl_fork() returns 0. The pcntl_fork() function returns -1 on failure in the parent process, with no children.


Fork process instance

The fork child processes.

$ppid = posix_getpid();

$pid = pcntl_fork();

if ($pid == -1) {

  throw new Exception('fork child process fail');

} elseif ($pid > 0) {

  cli_set_process_title("I am the parent process, pid is: {$ppid}.");

  sleep(30);

} else {

  $cpid = posix_getpid();

  cli_set_process_title("I'm a {$ppid} child process, my process pid is: {$cpid}.");

  sleep(30);

}
Copy the code

Description:

Posix_getpid () : Returns the id of the current process

Cli_set_process_title (‘ process name ‘) : Give the current process a loud name.

Running this example, we can see the current two PHP processes.

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ps aux | grep -v grep | grep I WWW 18026 0.5 1.2 204068 25772 PTS / 0 S + 14:08 0:00 I is the parent process, pid is: 18026. WWW 18027 0.0 0.3 204068 6640 PTS /0 S+ 14:08 0:00 MY process, my process PID is: 18027.Copy the code

In the first piece of code, the parent and child continue their respective execution of the code after the program passes from pcnTL_fork () :

$pid = pcntl_fork();

if( $pid > 0 ){

 echo "I am the father".PHP_EOL;

} else if( 0 == $pid ) {

 echo "I am the son.".PHP_EOL;

} else {

 echo "The fork failure".PHP_EOL; }Copy the code

Results:

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$PHP 123.php I am father I am sonCopy the code


The second code is used to say that the child has a copy of the parent’s data, rather than sharing it:

// Initialize a number variable with a value of 1$number = 1;

$pid = pcntl_fork();

if ($pid > 0) {

  $number+ = 1;echo "I am the father, number+1: {$number }" . PHP_EOL;

} else if(0 = =$pid) {

  $number+ = 2;echo "I'm the son, number+2: {$number }" . PHP_EOL;

} else {

  echo "The fork failure" . PHP_EOL;

}
Copy the code

The results of

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$PHP 1234. PHP number+1: {2} number+2: {3}Copy the code

I hope this will help you,Many PHPer will always encounter some problems and bottlenecks when they are advanced. They have no sense of direction because they write too much business code, so they don’t know where to start to improve. I have sorted out some information about this, including but not limited to: Distributed architecture, high scalability, high performance, high concurrency, server performance tuning, TP6, Laravel, YII2, Redis, Swoole, Swoft, Kafka, Mysql optimization, shell scripting, Docker, microservices, Nginx, etc. Many knowledge points can be shared for free
, you need toplease
Click here to
.