In PHP (pseudo) multi thread and multi process

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

(pseudo) multi thread: help

    To deal with the use of multi-threaded WEB server itself, from the WEB server called many times we need to achieve multi-threaded program.

QUOTE:

We know that PHP itself is not support multithreading, but our WEB server is to support multithreading.

That is to say, also let many people together. This is also the basis for access of multi thread in PHP I realized.

Suppose we are running a.php the file in the program. But I also request the WEB server running on a b.php

So these two files will be carried out simultaneously.

(later, PS: a link request the WEB server will execute it, regardless of whether the client has quit)

Sometimes, we want to run is not another file, but in this document is part of the code. How to do it?

In fact, but through the parameters to control the a.php to run a program.

Below an example:

[php] view plaincopy

  1. <?php  
  2. function runThread(){  
  3.     $fp = fsockopen('localhost', 80, $errno$errmsg);  
  4.     fputs($fp"GET /a.php?act=brnrn");//The second parameter is the request header specified in the HTTP agreement, do not understand please see the definition in the RFC                               
  5.     fclose($fp);  
  6. }  
  7. function a(){  
  8.     $fp = fopen('result_a.log''w');  
  9.     fputs($fp'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");  
  10.     fclose($fp);          
  11. }  
  12. function b(){  
  13.     $fp = fopen('result_b.log''w');  
  14.     fputs($fp'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");  
  15.     fclose($fp);          
  16. }  
  17. if(!isset($_GET['act'])){ $_GET['act'] = 'a';};  
  18.   
  19. if($_GET['act'] == 'a'){  
  20.     runThread();  
  21.     a();  
  22. }else if($_GET['act'] == 'b'){   
  23.     b();  
  24. };  
  25. ?>  

Access to open result_a.log and result_b.log compare two documents in time. You will find that, these two are running on different threads of.
some at exactly the same time.

The above is just a simple example, we can improve into other forms.


Since multiple threads can also be in the PHP, then the problem will come, that is the synchronization problem. We know that PHP itself is not support multithreading. So there will be no more like

Method Java synchronize. How do we do it.

1 as far as possible not to access the same resource. In order to avoid conflict. But at the same time as the database operation. Because the database is to support the concurrent operation. So in multiple threads in PHP

Don't write to the same file data. If you must write words, synchronization. Such as calling the flock lock files with other methods or create a temporary file.

Disappearance of while and wait for this file in another thread in (file_exits ('xxx')); this is equivalent to the existence of this temporary files, said that in fact the thread is operating

If without this file, the other thread has released it.

2 as far as possible not from runThread in the implementation of fputs after reading the data of the socket. Due to the implementation of multithread, non blocking mode need. In fgets like this

The function returns immediately. So the read and write data will be a problem. If using blocking mode, the program is not multithreaded. He wants to return to the above only execution

The following procedure. So if you need to exchange data and finally completed using outside a file or data. Really want it with socket_set_nonblock ($fp) to achieve.


Said so much, but at the end of this have no practical significance? Need this in this way when. ?

The answer is yes. You know, in a constantly read cyber source applications, the network speed is a bottleneck. If use this form can be simultaneously by multiple threads to

Different pages to read.

I do a soaso from the 8848, the mall site search information program. There is a reading of business information and company directory from Alibaba website also use

This technique. Because these two programs are to continue to link their server reads the information and save it to the database. Using this technique is to eliminate the waiting for a response.

Neck.
Multi process: the use of PHP Process Control Functions (PCNTL/ thread control function)
      function reference visible: http://www.php.net/manual/zh/ref.pcntl.php
      can only be used in the Unix Like OS, Windows is not available.
      when compiling PHP, You need to add --enable-pcntl, And recommend only run in CLI mode, Don't run in the WEB server environment.
      following the test code short:

[php] view plaincopy

  1. declare(ticks=1);  
  2. $bWaitFlag = FALSE; /// Whether to wait for the end of the process  
  3. $intNum = 10;           /// The total of processes  
  4. $pids = array();        ///  Process PID array  
  5. echo ("Start\n");  
  6. for($i = 0; $i < $intNum$i++) {  
  7.   $pids[$i] = pcntl_fork();/// The child process, and from below the current row open trial operation code, and not inherited from the parent process data information  
  8.   if(!$pids[$i]) {  
  9.     // The child process process code segment _Start  
  10.     $str="";  
  11.     sleep(5+$i);  
  12.     for ($j=0;$j<$i;$j++) {$str.="*";}  
  13.     echo "$i -> " . time() . " $str \n";  
  14.     exit();  
  15.     // The child process process code segment _End  
  16.   }  
  17. }  
  18. if ($bWaitFlag)  
  19. {  
  20.   for($i = 0; $i < $intNum$i++) {  
  21.     pcntl_waitpid($pids[$i], $status, WUNTRACED);  
  22.     echo "wait $i -> " . time() . "\n";  
  23.   }  
  24. }  
  25. echo ("End\n");  

Results are as follows:

CODE:[Copy toclipboard][qiao@oicq qiao]$ phptest.php       
Start
End
[qiao@oicq qiao]$ ps -aux | grep "php"
qiao     32275  0.0  0.5 49668 6148pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32276  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32277  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32278  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32279  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32280  0.0  0.5 49668 6152pts/1    S    14:03   0:00 /usr/local/php4/b
qiao     32281  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32282  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32283  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32284  0.0  0.5 49668 6152pts/1    S    14:03   0:00/usr/local/php4/b
qiao     32286  0.0  0.0  1620  600pts/1    S    14:03   0:00 grep php
[qiao@oicq qiao]$ 0 -> 1133503401 
1 -> 1133503402 *
2 -> 1133503403 **
3 -> 1133503404 ***
4 -> 1133503405 ****
5 -> 1133503406 *****
6 -> 1133503407 ******
7 -> 1133503408 *******
8 -> 1133503409 ********
9 -> 1133503410 *********

[qiao@oicq qiao]$
If $bWaitFlag=TURE, the result is as follows:

CODE:[Copy toclipboard][qiao@oicq qiao]$ phptest.php       
Start
0 -> 1133503602 
wait 0 -> 1133503602
1 -> 1133503603 *
wait 1 -> 1133503603
2 -> 1133503604 **
wait 2 -> 1133503604
3 -> 1133503605 ***
wait 3 -> 1133503605
4 -> 1133503606 ****
wait 4 -> 1133503606
5 -> 1133503607 *****
wait 5 -> 1133503607
6 -> 1133503608 ******
wait 6 -> 1133503608
7 -> 1133503609 *******
wait 7 -> 1133503609
8 -> 1133503610 ********
wait 8 -> 1133503610
9 -> 1133503611 *********
wait 9 -> 1133503611
End
[qiao@oicq qiao]$
From the multi process examples can be seen, the use of pcntl_fork (), will create a child process, and the child process running code, from pcntl_fork () after the code, and Zi Jin Cheng not inherited from the parent process data information (is actually the father process data to do a new copy), and the use of if (! $pids[$i]) code to control the actual operation of the process.

    A more detailed study for the time, temporarily not to, you can refer to the manual links.


[Article two] to try the PHP command line scripting multi process parallel execution

Author: dulao5
source:

In addition to fork, concurrent mode cli under another, see my example:


PHP does not support multiple threads, but we can put the problems into “ &rdquo to solve the multi process. Because PHP pcntl_fork only UNIX platform can use, so this paper attempts to use Popen instead.


The following is an example:

By the parallel call subroutine code:

[php] view plaincopy

  1. <?php  
  2. if($argc==1){  
  3.     echo("argv\n");  
  4. }  
  5. $arg = $argv[1];  
  6. for($i=0; $i<10; $i++)  
  7. {  
  8.     echo($i.".1.".time()." exec $arg \n");  
  9.     if($arg=='php2'){  
  10.         sleep(1);  
  11.         echo($i.".2.".time()." exec $arg \n");  
  12.         sleep(1);  
  13.     }else{  
  14.         sleep(1);  
  15.     }  
  16. }  
  17. ?>  

User program tone, he calls the child process, while the output of concurrent collection subroutine

[php] view plaincopy

  1. error_reporting(E_ALL);  
  2.   
  3. $handle1 = popen('php sub.php php1''r');  
  4. $handle2 = popen('php sub.php php2''r');  
  5. $handle3 = popen('php sub.php php3''r');  
  6.   
  7. echo "'$handle1'; " . gettype($handle1) . "\n";  
  8. echo "'$handle2'; " . gettype($handle2) . "\n";  
  9. echo "'$handle3'; " . gettype($handle3) . "\n";  
  10. //sleep(20);  
  11. while(!feof($handle1) || !feof($handle2) || !feof($handle3) )  
  12. {  
  13. $read = fgets($handle1);  
  14. echo $read;  
  15. $read = fgets($handle2);  
  16. echo $read;  
  17. $read = fgets($handle3);  
  18. echo $read;  
  19. }  
  20. pclose($handle1);  
  21. pclose($handle2);  
  22. pclose($handle3);  

Here is the output on our machine:

C:\my_hunter>php exec.php
'Resource id #4'; resource
'Resource id #5'; resource
'Resource id #6'; resource
0.1.1147935331 exec php1
0.1.1147935331 exec php2
0.1.1147935331 exec php3
1.1.1147935332 exec php1
0.2.1147935332 exec php2
1.1.1147935332 exec php3
2.1.1147935333 exec php1
1.1.1147935333 exec php2
2.1.1147935333 exec php3
3.1.1147935334 exec php1
1.2.1147935334 exec php2
3.1.1147935334 exec php3
4.1.1147935335 exec php1
2.1.1147935335 exec php2
4.1.1147935335 exec php3
5.1.1147935336 exec php1
2.2.1147935336 exec php2
5.1.1147935336 exec php3
6.1.1147935337 exec php1
3.1.1147935337 exec php2
6.1.1147935337 exec php3
7.1.1147935338 exec php1
3.2.1147935338 exec php2
7.1.1147935338 exec php3
8.1.1147935339 exec php1
4.1.1147935339 exec php2
8.1.1147935339 exec php3
9.1.1147935340 exec php1
4.2.1147935340 exec php2
9.1.1147935340 exec php3
5.1.1147935341 exec php2
5.2.1147935342 exec php2
6.1.1147935343 exec php2
6.2.1147935344 exec php2
7.1.1147935345 exec php2
7.2.1147935346 exec php2
8.1.1147935347 exec php2
8.2.1147935348 exec php2
9.1.1147935349 exec php2
9.2.1147935350 exec php2

**Summary: **

**The main program loop waits for the child process, get out through the output fgets or FREAD sub process, from the time stamp on look, indeed realize the concurrent execution. **

-----------------------------------------------
Future improvements:

*  Handle Popen open is a one-way interaction, if need to process, you can use proc_open
*  use arrays and functions instead of while (! Feof ($handle1) feof ($handle2) || ||!! feof ($handle3)) this dirty writing
*  output FREAD a child process has produced the take out, instead of one line at a time.

A concurrent shell task scheduling, the program reads a task file, each line command execution of concurrent inside, can the number of sub set of processes exist at the same time.:

[php] view plaincopy

  1. /* 
  2.    The main task manager 
  3.    The list of sub tasks concurrent execution 
  4. */  
  5. include("../common/conf.php");  
  6. include("../common/function.php");  
  7. //The number of processes running on the  
  8. $exec_number = 40 ;  
  9. /***** main ********/  
  10. if($argc==1){  
  11.     echo("argv\n");  
  12. }  
  13. $taskfile = $argv[1];  
  14. //tasklist  
  15. $tasklist = file($taskfile);  
  16. $tasklist_len = count($tasklist);  
  17. $tasklist_pos = 0;  
  18. $handle_list = array();  
  19. while(1)  
  20. {  
  21.     //The child process list are idle, then filled homogeneous sub process list  
  22.     if($exec_number > count($handle_list) &&  
  23.             $tasklist_pos < $tasklist_len)  
  24.     {  
  25.         for($i=$tasklist_pos$i<$tasklist_len; )  
  26.         {  
  27.             $command = $tasklist[$i] ;  
  28.             $handle_list[] = popen($command , "r" );  
  29.             tolog("begin task \t ".$tasklist[$i]);  
  30.             $i++;  
  31.             if($exec_number == count($handle_list)) break;  
  32.         }  
  33.         $tasklist_pos = $i;  
  34.     }  
  35.     //If the child process list is empty, exit  
  36.     if(0 == count($handle_list))  
  37.     {  
  38.         break;  
  39.     }  
  40.     //Check the output sub process list, to stop sub process is shut down and down  
  41.     $end_handle_keys = array();  
  42.     foreach($handle_list as $key => $handle)  
  43.     {  
  44.         //$str = fgets($handle, 65536);  
  45.         $str = fread($handle, 65536);  
  46.         echo($str);  
  47.         if(feof($handle))  
  48.         {  
  49.             $end_handle_keys[] = $key;  
  50.             pclose($handle);  
  51.         }  
  52.     }  
  53.     //Zi Jincheng kicked off  
  54.     foreach($end_handle_keys as $key)  
  55.     {  
  56.         unset($handle_list[$key]);  
  57.         //var_dump($handle_list);  
  58.         //exit;  
  59.     }  
  60.   
  61. }  
  62. tolog("\n\n*******************end**********************\n\n""" ,  true);  

Add a Socket multi process the received code:

[php] view plaincopy

  1. do {  
  2.  if (($msgsock = socket_accept($sock)) < 0) {  
  3.   echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";  
  4.   break;  
  5.  }  
  6.  $pid = pcntl_fork();  
  7.  if ($pid == -1) {  
  8.   die('could not fork');  
  9.  } else if (!$pid) {  
  10.   .....  
  11.   socket_write($msgsock$msgstrlen($msg));  
  12.   do {  
  13.    ......  
  14.   } while (true);  
  15.    socket_close($msgsock);  
  16.  }  
  17. while (true);  


The original address

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Enid at October 27, 2013 - 10:34 PM