How to realize multithreaded programming with PHP

Time:2022-7-25
catalogue
  • Multithreading
    • thread
    • Applicable scenarios
  • Multithreading in PHP
    • Thread safety
    • PHP implementation
    • Classes and methods
  • Example code
    • Asynchronous request
    • Timeout control
  • summary

    Multithreading

    thread

    First, let’s talk about threads:

    Thread is the smallest unit that the operating system can schedule operations. It is included in the process and is the actual operation unit in the process. A thread refers to a single sequential control flow in a process. Multiple threads can be concurrent in a process, and each thread executes different tasks in parallel

    Multithreading is mainly used because it has great advantages in execution efficiency. Because the thread is the smallest unit that the operating system can schedule:

    • A multithreaded program is more likely to be scheduled by the operating system than a single threaded program, so multithreaded programs are generally more efficient than single threaded programs;
    • Multiple threads of multithreaded program can run simultaneously in multiple cores of multi-core CPU, which can give full play to the advantage of multi-core machine;

    At the same time, compared with multi process programs, multi threading has the following characteristics:

    • The system overhead of thread creation and switching is smaller than that of processes, so it will be more efficient than multi processes to a certain extent;
    • Threads naturally share memory space, and the communication between threads is simpler, avoiding the new complexity introduced by process IPC.

    Applicable scenarios

    There are many optimizations of multithreading, but mindless use of multithreading can not improve the execution efficiency of programs, because the creation and destruction of threads, context switching, thread synchronization and so on also have performance losses, which may take more time than the code executed in sequence. For example:

    Sumsmall is a function that adds from 1 to 50000.

    The above figure shows the time comparison between executing sumsmall in the main thread three times and executing sumsmall in three threads respectively, and then synchronizing the results to one thread. We can find that the time of executing only in the main thread is shorter, and the time of creating, switching, and synchronizing the three threads is far greater than the time saved by asynchronous execution of threads.

    The function sumlarge increases from 1 to 5000000. In the following figure, the same thread executes three times and the execution time of three threads:

    This time, multithreading finally has an efficiency advantage.

    Whether to use multithreading depends on the specific needs. Generally, the following two situations should be considered:

    • I/o blocking will cause the operating system to schedule tasks and block the current task, so when there are many i/os in the code, the code can be parallel when using multithreading. For example, read the whole file multiple times, or request multiple network resources.
    • Multithreading can make full use of CPU, so when there are many large amount of code, multithreading can also be used to make them execute in parallel, such as the latter example in the above.

    Multithreading in PHP

    PHP does not support multithreading by default. To use multithreading, you need to install the pthread extension. To install the pthread extension, you must use the –enable-maintainer-zts parameter to recompile PHP. This parameter specifies the thread safe method to be used when compiling PHP.

    Thread safety

    Multithreading is a factor that makes programs uneasy. Before using multithreading, we should first consider thread safety:

    Thread safety: thread safety is a term in programming, which means that when a function or function library is called in a multithreaded environment, it can correctly handle the shared variables between multiple threads, so that the program function can be completed correctly.

    In traditional multithreading, because multiple threads share variables, the following problems may occur:

    1. There is a global array $arr = array (‘a’);;

    2. The length of the array obtained by thread a is 1;

    3. The length of the array obtained by the B thread is 1;

    4. A thread pop out the array element $a = array_ pop($arr); $ a = ‘a’;;

    5. B thread also pop array element $b = array_ pop($arr); $ a = null;;

    6. At this time, a supernatural event occurs in the B thread. It is clear that the length of the array is greater than 0, or there is no pop out;

    PHP implementation

    The thread safety realized by PHP mainly uses TSRM mechanism to isolate global variables and static variables, copy a copy of global variables and static variables to each thread, and each thread uses a backup of the main thread, so as to avoid variable conflict and thread safety problems.

    PHP’s encapsulation of multithreading ensures thread safety. Programmers do not need to consider adding various locks to global variables to avoid read-write conflicts. At the same time, it also reduces the chance of errors, and the written code is more secure.

    However, as a result, once the sub thread starts running, the main thread can no longer adjust the details of the sub thread, and the thread loses the ability to pass messages between threads through global variables to a certain extent.

    At the same time, after PHP turns on the thread safety option, there will be additional losses when using TSRM mechanism to allocate and use variables, so in a PHP environment that does not need multithreading, it is good to use the ZTS (non thread safety) version of PHP.

    Classes and methods

    PHP encapsulates threads into thread classes. The creation of threads is achieved by instantiating a thread object. Due to the encapsulation of classes, the use of variables can only be passed in through constructors, and the results of thread operations also need to be passed out through class variables.

    Here are some common thread class methods:

    • Run (): this method is an abstract method. Every thread should implement this method. After the thread starts running, the code in this method will be executed automatically;
    • Start (): call this method in the main thread to start running a thread;
    • Join (): each thread executes asynchronously relative to the main thread. Calling this method will wait for the end of thread execution;
    • Kill (): force the thread to end;
    • Isrunning (): returns the running state of the thread. When the thread is executing the code of the run () method, it will return true;

    Because of the implementation of thread safety, after PHP multithreads start running, they can no longer communicate through shared memory space, and threads can no longer be reused through inter thread communication. Therefore, I think PHP’s “thread pool” is meaningless. Built in extensionPoolClass is a class for multi-threaded allocation management, which will not be introduced here.

    Example code

    The following is a thread class used to request an interface. Next, write two multi-threaded application examples based on it:

    
    class Request extends Thread {
        public $url;
        public $response;
        public function __construct($url) {
            $this->url = $url;
        }
        public function run() {
            $this->response = file_get_contents($this->url);
        }
    }

    Asynchronous request

    Split the synchronous request into multiple thread asynchronous calls to improve the running efficiency of the program.

    
    $chG = new Request("www.google.com");
    $chB = new Request("www.baidu.com");
    $chG ->start();
    $chB ->start();
    $chG->join();
    $chB->join();
    
    $gl = $chG->response;
    $bd = $chB->response;

    Timeout control

    I happened to find a piece of content on a page of the company’s website sometimes without knowing the specific implementation, but this gave me the inspiration to use multithreading: using threads to achieve rapid failure and timeout control asynchronously.

    When we use curl to request an address, we can use curlopt_ CONNECTTIMEOUT / CURLOPT_ The timeout parameter sets the connection timeout and read data timeout of curl respectively, but the total timeout is not easy to control. Moreover, the timeout time for database query cannot be set (brother bird blog: set query timeout for MySQL).

    At this time, we can use multithreading to realize this function: after executing the start () method of the thread class, we do not call the join () method, so that the thread is always in an asynchronous state and does not block the execution of the main thread.

    At this time, the main thread is equivalent to the flagship, and each sub thread is equivalent to the cruise ship. After the flagship arrives at a certain place, it is not necessary to wait for the cruise ship to return, and then leave after waiting for a period of time, so as to avoid the flagship waiting in vain when the cruise ship is accidental.

    code:

    $chG = new Request("www.google.com");
    $chB = new Request("www.baidu.com");
    $chG->start();
    $chB->start();
    $chB->join();
    //The join method is not implemented here for CHG
    
    sleep(1); //  Sleep an acceptable timeout
    $gl = $chG->response;
    $bd = $chB->response;
    $bd->kill();
    if (!$gl) {
        $gl = ""; //  Handle exceptions, or give $gl a default value in the thread class
    }

    summary

    PHP’s blocking (Yan) and loading (GE) of multithreading makes people very unhappy with threads. Although it is safe and keeps the consistent style of PHP’s simplicity and ease of use, it can’t give full play to the ability of multithreading.

    The above is the details of how to use PHP to realize multithreaded programming. For more information about using PHP to realize multithreaded programming, please pay attention to other relevant articles of developeppaer!

    Recommended Today

    JS generate guid method

    JS generate guid method https://blog.csdn.net/Alive_tree/article/details/87942348 Globally unique identification(GUID) is an algorithm generatedBinaryCount Reg128 bitsNumber ofidentifier , GUID is mainly used in networks or systems with multiple nodes and computers. Ideally, any computational geometry computer cluster will not generate two identical guids, and the total number of guids is2^128In theory, it is difficult to make two […]