Analysis of Multi process and Example Source Code of PHP7

  • 2021-12-05 05:47:36
  • OfStack

Prepare

We all know that PHP is executed by a single process, and PHP mainly relies on the server or PHP-FPM multi-process and their process reuse, but PHP is also of great significance to realize multi-process, especially when processing a large amount of data in the background Cli mode or running the background DEMON daemon, the advantages of multi-process need not be said much.

The multithreading of PHP has also been mentioned, but it is difficult to solve the problem of resource sharing and allocation of multithreading in the process. PHP also has a multi-threaded extension pthreads, but it is said to be unstable and requires a thread-safe environment, so it is not used much.

In the past, a great god in the PHP group once instructed that the background PHP must avoid multi-process if it wants to advance. Just as the daemon in the company also applied the multi-process of PHP, combined with various materials and manuals of Gu Ge, it finally understood the multi-process, and wrote a small demo (implemented on linux system). Summarize it with this article. If there are any mistakes or omissions, thank you for putting forward it.

To implement multi-process PHP, we need two extensions, pcntl and posix, and the installation method will not be repeated here.

In php, we use pcntl_fork () to create multiple processes (in C language programming of * NIX system, existing processes generate new processes by calling fork functions). When fork comes out, the new process becomes a child process, while the original process becomes a parent process, and the child process has a copy of the parent process. Note here:

Child process shares program body segment with parent process

The child process owns the data space of the parent process and copies of the heap and stack. Note that it is a copy, not a share

The parent and child processes will continue to execute the program code after fork

After fork, whether the parent process executes first or the child process executes first cannot be confirmed, depending on system scheduling (depending on belief)

It is said that the child process has a copy of the parent process data space and the heap and stack. In fact, in most implementations, it is not really a complete copy. More is to use COW (Copy On Write), that is, write-time copy technology to save storage space. Simply put, if the parent process and child process do not modify these data, heap and stack, then the parent process and child process temporarily share the same data, heap and stack. Copy operations occur only when a parent or child process attempts to modify data, heap, or stack. This is called write-time copy.

After calling pcntl_fork (), the function returns two values. The process ID that returns the child process in the parent process and returns the number 0 inside the child process itself. Because multi-process in apache or fpm environment can not run normally, so everyone 1 must execute code in php cli environment.

Create a child process

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

Detailed Explanation of fork Function

pcntl_fork ()-Generates a branch (child process) at the current location of the current process. After this function creates a new child process, the child process will inherit the current context of the parent process, and continue to execute downward from the pcntl_fork () function like the parent process 1, but the return value of pcntl_fork () is different, so we can distinguish the parent process from the child process from the judgment return value, and allocate the parent process and the child process to do different logical processing.

When the pcntl_fork () function is successfully executed, the parent process will return the child process id (pid), because the pid of the initial process init of the system is 1, and the pid of the subsequent process will be greater than this process, so we can determine that the current process is the parent process by judging that the return value of pcntl_fork () is greater than 1; In the sub-process, the return value of this function will be a fixed value of 0, and we can also determine the sub-process by judging that the return value of pcntl_fork () is 0; When the pcntl_fork () function fails, it returns-1 in the parent process, and of course there are no children.

fork Process Instance

fork child process


$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 father  process , pid is : {$ppid}.");

  sleep(30);

} else {

  $cpid = posix_getpid();

  cli_set_process_title(" I am  {$ppid}  Sub-  process, Mine  process pid is : {$cpid}.");

  sleep(30);

}

Description:

posix_getpid (): Returns the current process id

cli_set_process_title ('Process Name'): Give the current process a loud name.

By 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 am the father  process , pid is : 18026.

www   18027 0.0 0.3 204068 6640 pts/0  S+  14:08  0:00  I  18026  Sub-  process, Mine  process pid is : 18027.   

The first code, after the program starts from pcntl_fork (), the parent process and the child process will each continue to execute the code:


$pid = pcntl_fork();

if( $pid > 0 ){

 echo " I'm the father ".PHP_EOL;

} else if( 0 == $pid ) {

 echo " I'm a son ".PHP_EOL;

} else {

 echo "fork Failure ".PHP_EOL;

}   

Results:


www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 123.php

 I'm the father 

 I'm a son 

The second section of code is used to explain that the child process owns the data copy of the parent process, not shares it:


//  Initialization 1 A  number Variable   The value is 1

$number = 1;

$pid = pcntl_fork();

if ($pid > 0) {

  $number += 1;

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

} else if (0 == $pid) {

  $number += 2;

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

} else {

  echo "fork Failure " . PHP_EOL;

}

Results


www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 1234.php

 I'm the father, number+1 : { 2 }

 I'm a son, number+2 : { 3 }


Related articles: