Non-blocking mode in PHP

Source: Internet
Author: User

The non-blocking mode of the program, which can be understood as concurrency. Concurrency can be dividedNetwork request concurrency
AndLocal concurrency
.

 

Network request concurrency

Theoretical description

Assuming there is a client, the program logic is to request three different servers to process their respective responses. The traditional model is of course sequential execution. First, the first request is sent, and then the second request is sent after the response data is received, and so on. It is like a single-core CPU. Only one task can be processed at a time, and other tasks are temporarily blocked. The concurrency mode allows three servers to process their respective requests at the same time, which can reuse a large amount of time.

Draw a picture to better illustrate the problem:

The former is the blocking mode, and the request response time is ignored. The total time consumed is 700 ms. The latter is the non-blocking mode. Because three requests can be processed at the same time, the total time consumed is only 300 ms.

 

Code Implementation

<? Php <br/> echo "program starts ". date ('H: I: s '). ". /n "; <br/> $ timeout = 3; <br/> $ sockets = array (); // socket handle array <br/> // initiate multiple requests at a time <br/> $ delay = 0; <br/> while ($ delay ++ <3) <br/>{< br/> $ SH = stream_socket_client ("localhost: 80", $ errno, $ errstr, $ timeout, <br/> stream_client_async_connect | stream_client_connect ); <br/>/* a slight delay is required. Otherwise, the socket handle in fwrite may not be actually used. <br/> This is a PHP bug. Check it, official bug as early as 08 years Someone submitted <br/> my 5.2.8 has not been resolved yet, and I wonder if it is corrected in the latest 5.3 <br/> */<br/> usleep (10 ); <br/> if ($ SH) {<br/> $ sockets [] = $ sh; <br/> $ http_header = "Get/test. PHP? N = {$ delay} HTTP/1.0/R/N "; <br/> $ http_header. = "Host: localhost/R/N"; <br/> $ http_header. = "accept: */R/N"; <br/> $ http_header. = "Accept-charset: */R/N"; <br/> $ http_header. = "/R/N"; <br/> fwrite ($ SH, $ http_header); <br/>}else {<br/> echo "Stream failed to open correctly. /n "; <br/>}< br/> // receives the response in non-blocking mode <br/> $ result = array (); <br/> $ read_block_size = 8192; <br/> while (count ($ sockets )) <Br/>{< br/> $ READ = $ sockets; <br/> $ n = stream_select ($ read, $ W = NULL, $ e = NULL, $ timeout); <br/> // if ($ n> 0) // It is said that the returned value of stream_select is not always trustable <br/> If (count ($ read )) <br/> {<br/>/* stream_select generally shuffles $ read, so we need to <br/> compute from which socket (s) We're reading. */<br/> foreach ($ read as $ R) <br/>{< br/> $ id = array_search ($ R, $ sockets ); <br/> $ DATA = fread ($ R, $ read_block _ Size); <br/> If (strlen ($ data) = 0) <br/>{< br/> echo "stream {$ id} closes ". date ('H: I: s '). ". /n "; <br/> fclose ($ R); <br/> unset ($ sockets [$ id]); <br/>} else {<br/> If (! Isset ($ result [$ id]) $ result [$ id] = ''; <br/> $ result [$ id]. = $ data; <br/>}< br/>} else {<br/> echo "time-out! /N "; <br/> break; <br/>}< br/> // print_r ($ result );

Notes:

1. Use the stream_socket_client function to link the server and port (the same address localhost is used here for simplicity ). HTTP protocol is not limited here and can be widely used in all TCP/IP protocols. For more information, see the manual.

2. After the connection is successful, different responses are obtained by sending their respective HTTP header information (test. php under the root directory of the website is used as the server ).

3. A small delay is required before the header is sent, and comments have been made in the Code.

 

CLI mode running result:

After running multiple times, you will find that the order of the three requests is unordered. This demo is too simple, resulting in the completion of the entire process within one second. However, you can delay the three different requests to see the effect of time reuse in non-blocking scenarios.

 

Next, let's talk about local concurrency.

Local concurrency can only achieve multi-tasking in the program itself through the features of the language itself. Generally, the current language is implemented through multithreading or multi-process. Because PHP does not support multithreading, you can only use the multi-process method to allow the operating system to help achieve local concurrency.

For code implementation, you can use pcntl extension (encapsulate fork and other process control functions, which are very similar to those used in C language and unavailable in Windows), proc_open, popen, and other methods. There are more than one method, I will not go into detail here. For more information, search for "php multi-process :)

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.