PHP多线程实现方法及使用示例详解

 2024-03-12 02:05:29  阅读 0

《:PHP多线程实现方法及使用示例详解》要点:

本文介绍:PHP多线程实现方法及使用示例详细讲解。 我希望它对你有用。 如果您有任何疑问,可以联系我们。

PHP实战 下面我们就来介绍具体的PHP多线程实现程序代码。 需要了解更多的同学可以参考一下。

当有人想要实现并发功能时,通常会想到使用fork或spawn,但是当他们发现PHP不支持多线程时,他们可能会改变主意并使用一些不够好的语言,例如perl。

事实是,在大多数情况下,您不需要使用 fork 或线程,并且会获得比使用 fork 或线程更好的性能。

假设您要构建一个服务来检查 n 个正在运行的服务器,以确保它们仍然正常运行。 您可能会编写如下代码:

代码如下所示

PHP实战
<?php
$hosts = array("host1.sample.com","host2.sample.com","host3.sample.com");
$timeout = 15;
$status = array();
foreach ($hosts as $host) {
 $errno = 0;
 $errstr = "";
 $s = fsockopen($host,80,$errno,$errstr,$timeout);
 if ($s) {
 $status[$host] = "Connectedn";
 fwrite($s,"HEAD / HTTP/1.0rnHost: $hostrnrn");
 do {
  $data = fread($s,8192);
  if (strlen($data) == 0) {
  break;
  }
  $status[$host] .= $data;
 } while (true);
 fclose($s);
 } else {
 $status[$host] = "Connection failed: $errno $errstrn";
 }
}
print_r($status);
?> 

它在 PHP 实践中工作得很好,但是扩展此代码来管理大量服务器将需要很长时间才能分析 () 并建立成功的连接(或延迟 $ 秒)。

因此我们必须放弃这段代码; 我们可以建立异步连接——无需等待连接状态返回。 PHP仍然需要解析(所以直接使用ip更明智),但是打开连接后会立即返回,然后我们就可以连接A服务器了。

有两种方法可以实现这一点:在PHP5中,可以使用new()函数直接()。 PHP5之前的版本,需要自己动手,使用扩展来解决问题。

PHP5中的解决方案如下:

代码如下所示

PHP实战
<?php
$hosts = array("host1.sample.com","host3.sample.com");
$timeout = 15;
$status = array();
$sockets = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id => $host) {
 $s = stream_socket_client("
$
$host:80",$timeout,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
 if ($s) {
 $sockets[$id] = $s;
 $status[$id] = "in progress";
 } else {
 $status[$id] = "failed,$errno $errstr";
 }
}
/* Now,wait for the results to come back in */
while (count($sockets)) {
 $read = $write = $sockets;
 /* This is the magic function - explained below */
 $n = stream_select($read,$write,$e = null,$timeout);
 if ($n > 0) {
 /* readable sockets either have data for us,or are failed
  * connection attempts */
 foreach ($read as $r) {
   $id = array_search($r,$sockets);
   $data = fread($r,8192);
   if (strlen($data) == 0) {
  if ($status[$id] == "in progress") {
  $status[$id] = "failed to connect";
  }
  fclose($r);
  unset($sockets[$id]);
   } else {
  $status[$id] .= $data;
   }
 }
 /* writeable sockets can accept an HTTP request */
 foreach ($write as $w) {
  $id = array_search($w,$sockets);
  fwrite($w,"HEAD / HTTP/1.0rnHost: "
  . $hosts[$id] . "rnrn");
  $status[$id] = "waiting for response";
 }
 } else {
 /* timed out waiting; assume that all hosts associated
  * with $sockets are faulty */
 foreach ($sockets as $id => $s) {
  $status[$id] = "timed out " . $status[$id];
 }
 break;
 }
}
foreach ($hosts as $id => $host) {
 echo "Host: $hostn";
 echo "Status: " . $status[$id] . "nn";
} 
?> 

在PHP实践中,我们使用()来等待打开连接事件。 ()调用系统的(2)函数进行工作:前三个参数是你要使用的数组; 你可以从中读取、写入和获取异常(分别为三个参数)。()可以通过设置$()参数来等待事件发生——当事件发生时,相应的数据将被写入到参数中你进来了。

以下是PHP 4.1.0之后版本的实现。 如果你在编译PHP时已经包含了(ext/)支持,那么可以使用上面类似的代码,但是需要使用ext/函数来实现上面/函数的功能。 主要区别在于我们使用下面的函数而不是()来建立连接:

代码如下所示

PHP实战
<?php
// This value is correct for Linux,other systems have other values
define('EINPROGRESS',115);
function non_blocking_connect($host,$port,&$errno,&$errstr,$timeout) {
 $ip = gethostbyname($host);
 $s = socket_create(AF_INET,SOCK_STREAM,0);
 if (socket_set_nonblock($s)) {
 $r = @socket_connect($s,$ip,$port);
 if ($r || socket_last_error() == EINPROGRESS) {
  $errno = EINPROGRESS;
  return $s;
 }
 }
 $errno = socket_last_error($s);
 $errstr = socket_strerror($errno);
 socket_close($s);
 return false;
}
?> 

PHP实践现在将()替换为(),将fread()替换为(),将()替换为(),将()替换为()来执行脚本!

PHP5 的高级之处在于,你可以使用 () 来处理几乎所有事情——例如,你可以使用它通过 STDIN 接收键盘输入并将其保存到数组中,还可以从通过 () 打开的管道接收数据。

标签: 线程 替换 实战

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码