Home Backend Development PHP Tutorial (Pseudo) Multithreading and Multiprocessing in PHP_PHP Tutorial

(Pseudo) Multithreading and Multiprocessing in PHP_PHP Tutorial

Jul 20, 2016 am 11:14 AM
php web and use deal with server of thread transfer process

(pseudo) multi-threading: with the help of external force

Utilize the multi-threading of the WEB server itself for processing, and call the program we need to implement multi-threading multiple times from the WEB server.

QUOTE:

We know that PHP itself does not support multi-threading, but our WEB server does support multi-threading.

That is to say, multiple people can access it at the same time. This is also the basis for me to implement multi-threading in PHP.

Suppose we are running the file a.php now. But I request the WEB server to run another b.php in the program

Then these two files will be executed at the same time.

(PS: After a link request is sent, the WEB server will execute it, regardless of whether the client has exited)

Sometimes, what we want to run is not another file, but a part of the code in this file. What should we do?

In fact, you can control which program a.php runs through parameters.

Look at an example below:

[php] view plaincopy
  1. function runThread(){
  2.  $fp = fsockopen('localhost', 80, $errno, $errmsg);
  3.  fputs($fp, "GET /a.php?act=brnrn");//The second parameter here is the request header specified in the HTTP protocol. If you don’t understand, please see the definition in the RFC. > fclose($fp
  4. ); }
  5. function
  6. a(){  $fp
  7. = fopen('result_a.log', 'w');  fputs
  8. ($fp, 'Set in '. Date('h:i:s', time()) . (double)microtime() . "rn"); fclose($fp
  9. ); }
  10. function
  11. b(){
  12.  $fp =
  13. fopen
  14. ('result_b.log', 'w');  fputs(
  15. $fp
  16. , 'Set in '. Date('h:i:s', time()) . (double)microtime() . "rn"); fclose($fp);
  17. }
  18. if(!isset(
  19. $_GET[
  20. 'act' ])){ $_GET['act'] = 'a';}; if(
  21. $_GET[
  22. 'act'] == 'a'){ runThread(); a();
  23. }
  24. else
  25. if(
  26. $_GET['act'] == 'b'){ b(); };
  27. ?>
  28. Open result_a.log and result_b.log and compare the access times of the two files. You will find that these two are indeed running in different threads. Some times are exactly the same.
  29. The above is just a simple example, you can improve it into other forms.
  30. Now that multi-threading is available in PHP, a problem arises, which is synchronization. We know that PHP itself does not support multi-threading. So there will be nothing like

The synchronize method in Java. So how should we do it.

1. Try not to access the same resource to avoid conflicts. But you can operate the database at the same time. Because the database supports concurrent operations, so in multi-threaded PHP

Do not write data to the same file. If you must write, use other methods for synchronization. For example, call flock to lock the file, etc. or create a temporary file

And wait for the file to disappear in another thread while(file_exits('xxx')); This means that when this temporary file exists, it means that the thread is actually operating

If this file no longer exists, it means that other threads have released this.

2. Try not to read data from the socket that runThread takes after executing fputs. Because to achieve multi-threading, it is necessary to use non-blocking mode. That is, like fgets

Such a function returns immediately. So there will be problems when reading and writing data. If blocking mode is used, the program is not multi-threaded. It has to wait for the above return before executing

The following program. So if you need to exchange data, you can finally use external files or data to complete it. If you really want it, use socket_set_nonblock($fp) to achieve it.


Having said so much, does this have any practical significance? When is it necessary to use this method?

The answer is yes. As we all know, in an application that constantly reads network resources, the speed of the network is the bottleneck. If you adopt this form, you can use multiple threads at the same time

Read different pages.

I made a program that can search for information from shopping mall websites such as 8848 and soaso. There is also a program that reads business information and company directories from the Alibaba website

This technology. Because both programs have to continuously connect to their servers to read information and save it to the database. Utilizing this technique just eliminates the bottle while waiting for a response

Neck.
Multi-process: Use PHP’s Process Control Functions (PCNTL/thread control function)
Function reference can be found at: http://www.php.net/manual/zh/ref.pcntl.php
Can only be used on Unix Like OS, not available on Windows.
When compiling php, you need to add --enable-pcntl, and it is recommended to run it only in CLI mode, not in a WEB server environment.
The following is a short test code:

[php] view plaincopy
  1. declare(ticks=1);
  2. $bWaitFlag = FALSE; /// Whether to wait for the process to end
  3. $intNum = 10; $pids =
  4. array
  5. (); 🎜> echo ("Startn");
  6. for($i = 0;
  7. $i
  8. < $intNum; $i++) { $pids[$i] = pcntl_fork();
  9. /// Spawn child process , and start the trial run code from the current line, and do not inherit the data information of the parent process
  10. if(!$pids[
  11. $i
  12. ]) { // Child process process code segment_Start  
  13. $str
  14. =""
  15. sleep(5+$i);  
  16. for
  17. ($j=0;
  18. $j
  19. < $i;$j++) {$str.="*";}  echo "$i -> " . time() .
  20. " $str n "
  21. ; exit();
  22. // Child process process code segment_End
  23. }
  24. }
  25. if
  26. (
  27. $bWaitFlag
  28. )
  29. {  for(
  30. $i
  31.  = 0;
  32. $intNum
  33. ; $i++) { pcntl_waitpid($pids[$i], $status , WUNTRACED);
  34. echo "wait $i -> " . time() . "n" ;
  35. } } echo (
  36. "Endn"
  37. );
  38. The running 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]$
    如果$bWaitFlag=TURE,则结果如下:

    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]$
    从 多进程的例子可以看出,使用pcntl_fork()之后,将生成一个子进程,而且子进程运行的代码,从pcntl_fork()之后的代码开始,而子进 程不继承父进程的数据信息(实际上是把父进程的数据做了一个全新的拷贝),因而使用if(!$pids[$i]) 来控制子进程实际运行的代码段。

        更详细的研究出于时间关系,暂时没有进行,你可以参考我给出的手册的链接。


    [文章二] 尝试php命令行脚本多进程并发执行

    作者:dulao5
    来源:http://dulao5.blog.hexun.com/3726837_d.html

    除了fork, cli下的并发方式还有一种,看我的例子:


    php不支持多线程,但是我们可以把问题转换成“多进程”来解决。由于php中的pcntl_fork只有unix平台才可以使用,所以本文尝试使用popen来替代。


    下面是一个例子:

    被并行调用的子程序代码:

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

     

    主调用者程序,由他调用子进程,同时并发的收集子程序的输出

    [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);  

     

    下面是我机器上的输出:

    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

    **总结:**

    **主程序循环等待子进程, 通过fgets或fread 把子进程的输出获取出来 , 从时间戳上看,的确实现了并发执行。**

    -----------------------------------------------
    以后的改进:

    *  popen打开的句柄是单向的,如果需要向子进程交互,可以使用proc_open
    *  使用数组和子函数代替while(!feof($handle1)|| !feof($handle2) || !feof($handle3) )这种龌龊的写法
    *  用fread一次把子进程已经产生的输出取完,而不是每次一行。

    一个并发执行shell任务的调度者,本程序读取一个任务文件,把里面的每行命令并发执行, 可以设置同时存在的子进程数目:

    [php] view plaincopy
    1. /*
    2. Main Task Manager
    3. Concurrent execution sub-task list
    4. */
    5. include("../common/conf.php");
    6. include("../common/function.php");
    7. //Number of opened processes
    8. $exec_number = 40 ;
    9. /***** main ********/
    10. if($argc==1){
    11. echo("argvn");
    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. //If the child process list is free, fill in the child 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.  
    28. $command = $tasklist[$i]; 🎜>  
    29. $handle_list
    30. [] = popen($command , "r" ); tolog(
    31. "begin task t "
    32. .$tasklist[$i]);
    33. $i
    34. ++;  
    35. if
    36. ($exec_number == count( $handle_list)) break;                                                                                  
    37. $tasklist_pos
    38. =
    39. $i; }
    40. //If the child process list is empty, exit
    41.  if
    42. (0 ==
    43. count($handle_list)) {
    44. break
    45. ;
    46. }
    47. //Check the output of the child process list, close the stopped child process and record it
    48. $end_handle_keys = array();
    49. foreach($handle_list as $key => $handle)
    50. {
    51. //$str = fgets($handle, 65536);
    52.  $str = fread($handle, 65536);
    53. echo($str);
    54.  if(feof($handle))
    55.                                              
    56.  
    57. $end_handle_keys[] = $key
    58. pclose(
    59. $handle);
    60.                                                                                  
    61. }
    62. //Kick out the stopped child process
    63. foreach
    64. ($end_handle_keys as $key) {
    65. unset($handle_list
    66. [$key]); //var_dump($handle_list);
    67.  //exit;
    68.   }
    69. }
    70. tolog("nn************************end********************** *****nn"
    71. , "" , true);
    72. Attach a piece of code for Socket multi-process reception:
    [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);  


    原文地址:http://www.alixixi.com/program/a/2008050731686.shtml

    www.bkjia.comtruehttp://www.bkjia.com/PHPjc/440281.htmlTechArticle(伪)多线程:借助外力 利用WEB服务器本身的多线程来处理,从WEB服务器多次调用我们需要实现多线程的程序。 QUOTE: 我们知道PHP本身是不支...
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles