您的位置  > 互联网

php中不可以使用PHP多线程的方法和函数有关

更新时间:2016年10月14日 11:44:25 作者:新闻

多线程在Java中是一个非常好的东西。 很多朋友说PHP中不能使用PHP多线程。 事实上,这是一个错误的说法。 本文介绍PHP中多线程的两种实现方法。 有兴趣的同学可以看一下。

PHP本身是否支持多线程,但是我们可以使用其他方法来实现多线程,比如shell服务,比如web服务器。 在这篇文章中,我们将讨论如何实现这两种方法。 有需要的朋友可以过来参考一下。

多线程在Java中是一个非常好的东西。 很多朋友说PHP中不能使用PHP多线程。 事实上,这是一个错误的说法。 PHP多线程的实现方法与函数有关。 下面介绍一下具体的实现程序代码。 需要了解更多的同学可以参考一下。

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

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

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

代码如下所示:

<?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仍然需要解析(所以直接使用IP更明智),但是打开连接后它会立即返回,然后我们可以连接到下一个服务器。

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

PHP5中的解决方案如下:

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

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

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

代码如下所示:

<?php
$hosts = array("host1.sample.com", "host2.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", $errno, $errstr, $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";
} 
?> 

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

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

代码如下所示:

<?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;
}
?> 

现在将()替换为(),将fread()替换为(),将()替换为(),将()替换为(),就可以执行脚本了!

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