How to summarize _php techniques in PHP programming with concurrent methods

Source: Internet
Author: User
Tags curl error handling php class php programming sleep

This article summarizes approximately five concurrent methods in PHP Programming:
1.curl_multi_init
The document says allows the processing of multiple curl Handles asynchronously. is really asynchronous. What needs to be understood here is the Select method, which is interpreted in the document as blocks until there is, the "any of" curl_multi connections. Understanding the common asynchronous model should be understandable, select, Epoll, are well-known

 <?php/build the individual requests as above, but does not execute them $ch _1 = Curl_
Init (' http://www.jb51.net/');
$ch _2 = curl_init (' http://www.jb51.net/');
curl_setopt ($ch _1, Curlopt_returntransfer, true);

curl_setopt ($ch _2, Curlopt_returntransfer, true);
Build the Multi-curl handle, adding both $ch $mh = Curl_multi_init ();
Curl_multi_add_handle ($MH, $ch _1);

Curl_multi_add_handle ($MH, $ch _2);
Execute all queries simultaneously, and continue the all are complete $running = null;
  do {curl_multi_exec ($MH, $running);
  $ch = Curl_multi_select ($MH);
    if ($ch!== 0) {$info = Curl_multi_info_read ($MH);
      if ($info) {var_dump ($info);
      $response _1 = curl_multi_getcontent ($info [' handle ']);
      echo "$response _1 \ n";
    Break

}} while ($running > 0);
Close the handles Curl_multi_remove_handle ($MH, $ch _1);
Curl_multi_remove_handle ($MH, $ch _2);

Curl_multi_close ($MH); 

What I set here is that when the select gets the result, it exits the loop and deletes the curl resource to cancel the HTTP request.

2.swoole_client
Swoole_client provides asynchronous mode, I forgot this. The sleep method here requires a swoole version greater than or equal to 1.7.21, and I haven't been able to get to this version, so direct exit is OK.

<?php
$client = new Swoole_client (swoole_sock_tcp, swoole_sock_async);
Set the event callback function
$client->on ("Connect", function ($CLI) {
  $req = "get/http/1.1\r\n
  host:www.jb51.net\r\n
  connection:keep-alive\r\n
  cache-control:no-cache\r\n
  pragma:no-cache\r\n\r\n ";

  For ($i =0 $i < 3 $i + +) {
    $cli->send ($req);
  }
);
$client->on ("Receive", Function ($CLI, $data) {
  echo "Received:". $data. " \ n ";
  Exit (0);
  $cli->sleep (); Swoole >= 1.7.21
});
$client->on ("Error", function ($CLI) {
  echo "Connect failed\n";
});
$client->on ("Close", function ($CLI) {
  echo "Connection close\n";
});
Initiate network connection
$client->connect (' 183.207.95.145 ', 80, 1);

3.process
Hey, almost forgot the swoole_process, there is no pcntl module. But after writing the discovery, this is not actually a interrupt request, but which one to read first, ignoring the return value after.

 <?php $workers = []; $worker _num = 3;//The number of processes created $finished = false; $lock = new swoole_l

Ock (Swoole_mutex);
  For ($i =0 $i < $worker _num $i + +) {$process = new swoole_process (' process ');
  $process->usequeue ();
  $pid = $process->start ();
$workers [$pid] = $process; The foreach ($workers as $pid => $process) {//subprocess will also contain this event Swoole_event_add ($process->pipe, function ($pipe) use ($PR
    Ocess, $lock, & $finished) {$lock->lock ();
      if (! $finished) {$finished = true;
      $data = $process->read (); echo "RECV:". $data.
    Php_eol;
  } $lock->unlock ();
});
  The function process (swoole_process $process) {$response = ' http response ';
  $process->write ($response); echo $process->pid, "T", $process->callback.
Php_eol;
  for ($i = 0; $i < $worker _num $i + +) {$ret = Swoole_process::wait ();
  $pid = $ret [' pid ']; echo "Worker Exit, pid=". $pid.
Php_eol; }

4.pthreads
when compiling the Pthreads module, you are prompted to open the Zts when PHP compiles, so it appears that the thread safe version must be available. Wamp PHP is just the TS, directly under the DLL, the document in the instructions copied to the corresponding directory, the win under the test. Not fully understood, found that the article said PHP pthreads and POSIX pthreads is completely different. Code is a bit rotten, but also need to look at the document, experience.

<?php
class Foo extends stackable {public
  $url;
  public $response = null;
  Public Function __construct () {
    $this->url = ' http://www.jb51.net ';
  }
  Public Function Run () {}
}

class Process extends Worker {
  private $text = "";
  Public function __construct ($text, $object) {
    $this->text = $text;
    $this->object = $object;
  }
  Public Function run () {while
    (Is_null ($this->object->response)) {
      print Thread {$this->text} is Running\n ";
      $this->object->response = ' http response ';
      Sleep (1);

}}} $foo = new Foo ();

$a = new Process ("a", $foo);
$a->start ();

$b = new Process ("B", $foo);
$b->start ();

Echo $foo->response;

5.yield
to write asynchronous code synchronously:

<?php class Asyncserver {protected $handler; 
  protected $socket; 
  protected $tasks = []; 
 
  protected $timers = []; 
 
    Public function __construct (callable $handler) {$this->handler = $handler; 
    $this->socket = socket_create (Af_inet, Sock_dgram, SOL_UDP); if (! $this->socket) {die Socket_strerror (Socket_last_error ()). " 
    \ n "); } if (!socket_set_nonblock ($this->socket)) {die (Socket_last_error ()). " 
    \ n "); } if (!socket_bind ($this->socket, 0.0.0.0, 1234)) {die (Socket_strerror ()). " 
    \ n "); 
      The Public Function Run () {while (true) {$now = Microtime (True) * 1000; 
        foreach ($this->timers as $time => $sockets) {if ($time > $now) break; 
          foreach ($sockets as $one) {list ($socket, $coroutine) = $this->tasks[$one]; 
          unset ($this->tasks[$one]); 
          Socket_close ($socket); $coroutinE->throw (New Exception ("Timeout")); 
      } unset ($this->timers[$time]); 
      } $reads = Array ($this->socket); 
      foreach ($this->tasks as List ($socket)) {$reads [] = $socket; 
      } $writes = NULL; 
      $excepts = NULL; 
      if (!socket_select ($reads, $writes, $excepts, 0, 1000)) {continue; 
        foreach ($reads as $one) {$len = Socket_recvfrom ($one, $data, 65535, 0, $ip, $port); 
          if (! $len) {//echo "Socket_recvfrom fail.\n"; 
        Continue } if ($one = = $this->socket) {//echo] [run]request recvfrom succ. 
          Data= $data ip= $ip port= $port \ n "; 
          $handler = $this->handler; 
          $coroutine = $handler ($one, $data, $len, $ip, $port); 
            if (! $coroutine) {//echo "[run]everything is done.\n"; 
          Continue 
          $task = $coroutine->current (); echo "[Run]asynctask RecV. data= $task->data ip= $task->ip port=->port $task timeout= $task->timeout\n "; 
          $socket = Socket_create (Af_inet, Sock_dgram, SOL_UDP); if (! $socket) {//echo socket_strerror (Socket_last_error ()). " 
            \ n "; 
            $coroutine->throw (New Exception (Socket_strerror (Socket_last_error ()), Socket_last_error ()); 
          Continue } if (!socket_set_nonblock ($socket)) {//echo socket_strerror (Socket_last_error ()). " 
            \ n "; 
            $coroutine->throw (New Exception (Socket_strerror (Socket_last_error ()), Socket_last_error ()); 
          Continue 
          Socket_sendto ($socket, $task->data, $task->len, 0, $task->ip, $task->port); 
          $deadline = $now + $task->timeout; 
          $this->tasks[$socket] = [$socket, $coroutine, $deadline]; 
        $this->timers[$deadline] [$socket] = $socket; else {//echo] [run]response recvfrom succ. Data= $data ip= $ip port= $port \ n "; 
          List ($socket, $coroutine, $deadline) = $this->tasks[$one]; 
          unset ($this->tasks[$one]); 
          unset ($this->timers[$deadline] [$one]); 
          Socket_close ($socket); 
        $coroutine->send (Array ($data, $len)); 
  Class Asynctask {public $data}}}} 
  Public $len; 
  Public $ip; 
  Public $port; 
 
  Public $timeout; 
    Public function __construct ($data, $len, $ip, $port, $timeout) {$this->data = $data; 
    $this->len = $len; 
    $this->ip = $ip; 
    $this->port = $port; 
  $this->timeout = $timeout; } function Asyncsendrecv ($req _buf, $req _len, $ip, $port, $timeout) {return new Asynctask ($req _buf, $req _len, $ip 
, $port, $timeout); function RequestHandler ($socket, $req _buf, $req _len, $ip, $port) {//echo "[RequestHandler] before yield . 
  req= $req _buf\n "; try {list ($rsp _buf, $rsp _len) = (yield Asyncsendrecv ($req _buf, $req _len, "127.0.0.1", 2345, 3000)); 
    The catch (Exception $ex) {$rsp _buf = $ex->getmessage (); 
    $RSP _len = strlen ($rsp _buf); 
  echo "[Exception] $rsp _buf\n"; //echo "[RequestHandler] after yield asynctask. 
  rsp= $rsp _buf\n "; 
Socket_sendto ($socket, $rsp _buf, $rsp _len, 0, $ip, $port); 
} $server = new Asyncserver (RequestHandler); 
 
$server->run (); 
 ?>

Code interpretation:

The use of PHP built-in array capabilities, to achieve a simple "time-out management", in milliseconds as the precision of time slicing;
Encapsulates ASYNCSENDRECV interfaces, calling shapes such as yield asyncsendrecv (), more natural;
Add exception as an error handling mechanism, add ret_code can also be used for display only.

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.