Explore PHP's multi-process programming approach and explore PHP process programming _php Tutorials

Source: Internet
Author: User

Explore PHP's multi-process programming approach and explore PHP process programming


Creation of child processes
The general child process is written as:

<?php$pid = Pcntl_fork (); if ($pid = =-1) {     //Create failed Die     (' could not fork ');} else{    if ($pid) {        //The code written from here is the        exit ("parent!") of the parent process;    }    else{        //Sub-process code, in order to prevent the continuous activation of child processes caused by the exhaustion of system resources, the general sub-process code after the completion of the execution, add exit to ensure that the child process exit gracefully.        exit ("Child");}    ? >

The above code if the creation of the child process succeeds, the system has 2 processes, one for the parent process, one for the child process, the child process ID number is $pid. When the system is running to $pid = Pcntl_fork (); At this point, the parent-child process begins to run its own program code. The result of the code running is parent and child, and it's strange why the results are output in an if and else mutex code? In fact, as the above said, when the code is pcntl_fork, a parent process runs the father, and a child process runs the children. The parent and child are displayed on the code results. As for the question of who first, it depends on the allocation of the system resources.

If more than one process is required to process the data, the screwdriver process can be based on the number of data, such as the number of agreed quantities, such as 1000 processes. You can use the For loop.

#如果获得的总数小于或等于0, wait 60 seconds, and exit  if ($count <= 0)   {    sleep];    Exit;  }  #如果大于1000, calculate the number of processes required  if ($count >)  {    $cycleSize = ceil ($count/1000);  }  else  {    $cycleSize = 1;  }    for ($i =0; $i < $cycleSize; $i + +)  {    $pid  = Pcntl_fork ();    if ($pid = =-1)    {break      ;    }    else    {      if ($pid)      {        #父进程获得子进程的pid, the array is deposited        $pidArr [] = $pid;      }      else      {        //start sending, and the child process exits after executing its own task.          exit  ;    }}} while (count ($PIDARR) > 0)  {    $myId  = Pcntl_waitpid ( -1, $status, Wnohang);    foreach ($pidArr as $key = + $pid)    {      if ($myId = = $pid) unset ($PIDARR [$key]);}  }

Then use crontab to automate this PHP program every once in a while.

Of course, the sample code is relatively simple, but also to consider how to prevent the execution of multiple child processes to the same data or the current process processing data is not completed, Crontab began to execute PHP files to enable the new process and so on.


PHP Multi-process implementation mode
Here is a systematic way to organize the implementation of multiple PHP processes:

1. Direct Way

Pcntl_fork () creates a process in which the parent process returns a value that is the PID of the child process, and the return value in the child process is 0,-1 indicates that the creation process failed. Very similar to C.

Test Script test.php

<?php  //Example of multiple processes  date_default_timezone_set (' asia/chongqing ');  echo "Parent start, pid", Getmypid (), "\ n";  Beep ();  for ($i =0; $i <3; + + $i) {     $pid = Pcntl_fork ();      if ($pid = =-1) {die         ("Cannot fork"),     } else if ($pid > 0) {         echo "parent continue \ n";         for ($k =0; $k <2; + + $k) {           beep ();        }     } else if ($pid = = 0) {         echo "child start, pid", Getmypid (), "\ n" ;         for ($j =0; $j <5; + + $j) {           beep ();        }         Exit;     }  }  function beep () {      echo getmypid (), "\ T", Date (' y-m-d h:i:s ', Time ()), "\ n";     Sleep (1);  }? >

Run with command line

#php-F test.php

Output results

Parent start, PID 17931793  2013-01-14 15:04:17parent continue1793  2013-01-14 15:04:18child start, PID 17941794< c2/>2013-01-14 15:04:181794  2013-01-14 15:04:191793  2013-01-14 15:04:191794  2013-01-14 15:04:20parent continue1793  2013-01-14 15:04:20child start, pid 17951795  2013-01-14 15:04:2017931794        2013-01-14 15:04:212013-01-14 15:04:211795  2013-01-14 15:04:211794  2013-01-14 15:04:221795  2013-01-14 15:04:22parent continue1793  2013-01-14 15:04:22child start, pid 17961796  2013-01-14 15:04:221793 2013-01-14 15:04:231796  2013-01-14 15:04:231795  2013-01-14 15:04:231795  2013-01-14 15:04:241796  2013-01-14 15:04:241796  2013-01-14 15:04:251796  2013-01-14 15:04:26

As you can see, 3 child processes are created and run in parallel with the parent process. One of the lines is a little different from the others,
17931794 2013-01-14 15:04:212013-01-14 15:04:21
The conflict is caused by the simultaneous write operation of two processes.


2. Blocking mode

In a direct way, after the parent process creates the child process, it does not wait for the child process to end, but continues to run. There seems to be no problem here. If the PHP script does not end automatically after it finishes running, it will cause the child process to be unable to reclaim because it is resident memory. That's the zombie process. You can wait for the process to end through the Pcntl_wai () method, and then reclaim the process that has ended.
Change the test script to:

$pid = Pcntl_fork (), if ($pid = =-1) {  ...} else if ($pid > 0) {   echo "parent continue \ n";   Pcntl_wait ($status);   for ($k =0; $k <2; + + $k) {     beep ();  }} else if ($pid = = 0) {   ...}

Run with command line

#php-F test.php

Output results

Parent start, PID 18071807  2013-01-14 15:20:05parent continuechild start, pid 18081808  2013-01-14 15:20:061808< c2/>2013-01-14 15:20:071808  2013-01-14 15:20:081808  2013-01-14 15:20:091808  2013-01-14 15:20:101807  2013-01-14 15:20:111807  2013-01-14 15:20:12parent continuechild start, pid 18091809  2013-01-14 15:20:131809  2013-01-14 15:20:141809  2013-01-14 15:20:151809  2013-01-14 15:20:161809  2013-01-14 15:20:171807  2013-01-14 15:20:181807  2013-01-14 15:20:19child start, PID 18101810  2013-01-14 15:20:20parent continue1810  2013-01-14 15:20:211810  2013-01-14 15:20:221810  2013-01-14 15:20:231810  2013-01-14 15:20:241807  2013-01-14 15:20:251807  2013-01-14 15:20:26

The parent process blocks itself in pcntl_wait (), waiting for the child process to run.


3. Non-blocking mode

Blocking mode loses the parallelism of many processes. There is also a way to reclaim a child process that has ended and can be parallel. This is a non-blocking approach.
To modify a script:

<?php//Example of multiple processes Date_default_timezone_set (' asia/chongqing ');  DECLARE (ticks = 1);  Pcntl_signal (SIGCHLD, "garbage");  echo "Parent start, pid", Getmypid (), "\ n";  Beep ();      for ($i =0; $i <3; + + $i) {$pid = Pcntl_fork ();     if ($pid = =-1) {die ("Cannot fork");         } else if ($pid > 0) {echo "parent continue \ n";        for ($k =0; $k <2; + + $k) {beep ();         }} else if ($pid = = 0) {echo "Child start, pid", Getmypid (), "\ n";        for ($j =0; $j <5; + + $j) {beep ();     } exit (0);  }}//Parent while (1) {//do something else sleep (5);            }//* * * function garbage ($signal) {echo "SiGNeL $signal received\n";     while ($pid = Pcntl_waitpid ( -1, $status, Wnohang) > 0) {echo "\ t child end PID $pid, status $status \ n";     }} function beep () {echo getmypid (), "\ T", Date (' y-m-d h:i:s ', Time ()), "\ n";  Sleep (1); }?>

Run with command line

#php-F test.php &

Output results

Parent start, PID 20662066  2013-01-14 16:45:34parent continue2066  2013-01-14 16:45:35child start, PID 20672067< c2/>2013-01-14 16:45:3520662067        2013-01-14 16:45:362013-01-14 16:45:362067  2013-01-14 16:45:37parent continue2066  2013-01-14 16:45:37child start, pid 20682068  2013-01-14 16:45:372067  2013-01-14 16:45:382068  2013-01-14 16:45:382066  2013-01-14 16:45:38parent continue2066  2013-01-14 16:45:40child Start, PID 20692069  2067  2013-01-14 16:45:402013-01-14 16:45:402068  2013-01-14  16:45:402066 2013-01-14 16:45:412069  2013-01-14 16:45:412068  2013-01-14 16:45:41signel + received child     end PID 2067, status 02069  2013-01-14 16:45:422068  2013-01-14 16:45:422069 2013-01-14  16:45:43signel 17 Received child     end PID 2068, status 02069  2013-01-14 16:45:44signel-Received child     end PID 2069, status 0

Multiple processes run in parallel and run for about 10 seconds, using Ps-ef | grep php to view a running process with only one process
Lqling 2066 1388 0 16:45 pts/1 00:00:00 php-f t5.php
Is the parent process, and the child process is recycled.


Child process Exit status

Pcntl_waitpid ( -1, $status, Wnohang) $status

Returns the end state of a child process


Multithreading under Windows

Windows does not support the PCNTL function, fortunately there is curl_multi_exec () This tool, the use of internal multi-threading, access to multiple links, each link can be used as a task.

Writing a script test1.php

<?php date_default_timezone_set (' asia/chongqing '); $tasks = Array (' Http://localhost/feedbowl/t2.php?job=task1 ', ' http://localhost/feedbowl/t2.php?job=task2 ', ' H  Ttp://localhost/feedbowl/t2.php?job=task3 ');  $MH = Curl_multi_init ();     foreach ($tasks as $i = = $task) {$ch [$i] = Curl_init ();     curl_setopt ($ch [$i], Curlopt_url, $task);     curl_setopt ($ch [$i], Curlopt_returntransfer, 1);  Curl_multi_add_handle ($MH, $ch [$i]);  } do {$MRC = Curl_multi_exec ($MH, $active), and while ($MRC = = Curlm_call_multi_perform);  while ($active && $MRC = = CURLM_OK) {if (Curl_multi_select ($MH)! =-1) {do {$MRC = Curl_multi_exec ($MH, $active);     } while ($MRC = = Curlm_call_multi_perform); }}//Completed, checkout result foreach ($tasks as $j = + $task) {if (Curl_error ($ch [$j]) {echo "task ${     J} [$task] Error ", Curl_error ($ch [$j])," \ r \ n ";  } else {echo "task ${j} [$task] get: \ r \ n", Curl_multi_getcontent ($ch [$j]), "\ r \ n";   }}?> 

Writing a script test2.php

<?php  date_default_timezone_set (' asia/chongqing ');  echo "Child start, pid", Getmypid (), "\ r \ n";  for ($i =0; $i <5; + + $i) {     beep ();  }  Exit (0);  function beep () {    echo getmypid (), "\ T", Date (' y-m-d h:i:s ', Time ()), "\ r \ n";    Sleep (1);  }? >

Run with command line

#php-F test1.php &

Output results

Task 0 [Http://localhost/feedbowl/t2.php?job=task1] get:child start, PID 58045804  2013-01-15 20:22:355804  2013-01-15 20:22:365804  2013-01-15 20:22:375804  2013-01-15 20:22:385804  2013-01-15 20:22:39task 1 [http ://localhost/feedbowl/t2.php?job=task2] get:child start, PID 58045804  2013-01-15 20:22:355804  2013-01-15 20:22:365804  2013-01-15 20:22:375804  2013-01-15 20:22:385804  2013-01-15 20:22:39task 2 [/HTTP// LOCALHOST/FEEDBOWL/T2.PHP?JOB=TASK3] get:child start, PID 58045804  2013-01-15 20:22:355804  2013-01-15 20:22:365804  2013-01-15 20:22:375804  2013-01-15 20:22:385804  2013-01-15 20:22:39

As seen from the time of printing, multiple tasks run almost simultaneously.

http://www.bkjia.com/PHPjc/1049142.html www.bkjia.com true http://www.bkjia.com/PHPjc/1049142.html techarticle Explore PHP's multi-process programming method, explore the PHP process programming sub-process of the creation of a generic sub-process is: Php$pid = Pcntl_fork (); if ($pid = =-1) {//Create failed die (' Coul ...

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.