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 ...