【发布时间】:2019-02-28 15:35:42
【问题描述】:
在过去的 3.5 年里,我一直在编写 PHP,我喜欢它。当最近的 PHP v/s Nodejs 热议出现时,总是引起关注的一件事是 Nodejs 实现了非阻塞(或异步)I/O默认情况下,PHP 没有。
但是,当我最近尝试在 PHP 中实现一个简单的异步请求路由器(使用 exec() 函数)并尝试将我的代码与标准(假设是同步请求处理程序脚本)进行对比时,我注意到奇怪的东西。
在进一步解释之前,我希望您看一下下面的代码。
sync.php:应该暂停所有进一步的请求,直到当前请求完成处理:
<?php
$a = $argv[1];
echo "starting: ".$a;
$ar = array();
$sum = 0;
$ul = 15000;
for($i = 1; $i < $ul; $i++){
$ar[$i] = $i;
}
for($i = 1; $i < $ul; $i++){
for($j = 1; $j < $ul; $j++){
$sum += $ar[$j];
}
}
echo "\n\nDone: ".$a."\nResult: ".$sum."\n";
?>
我做了两种测试。
首先,我在我的电脑上运行了四个终端实例并执行:
php sync.php 1
所有这些同时。
接下来,我打开了我的 XAMPP 服务器,通过serveo 暴露了我的本地主机,并同时从三个不同的设备向这个脚本发出了三个请求。
结果出乎意料。
无论我发送多少请求,所有请求(似乎)都会并行执行,并且结果(几乎)同时显示在所有终端窗口/浏览器选项卡上(考虑到 1-2 秒的延迟在每个终端窗口中手动运行命令时发生)。
这不符合 PHP 实现阻塞 I/O 的事实(这就是我的想法)。相反,我期望的是获得
的总爆发时间n * 4 seconds
其中 n 是处理每个请求所花费的时间(在我的笔记本电脑上大约 8 秒)。
那么,为什么会异步处理请求?是因为 for 循环 是异步执行的函数之一,还是与阻塞 I/O 模型根本没有任何关系??
【问题讨论】:
-
单个 PHP 进程 阻塞。这就是为什么网络服务器在 FPM 池或一堆 Apache 工作人员中运行多个。您基本上做了同样的事情 - 您在四个单独的终端窗口中运行了四个单独的 PHP 进程。
-
是的,PHP 中的服务器是多进程的(而 NodeJs 的缺点是它是单进程的,这可能是他们必须实现异步的原因)
-
@ceejayoz 那么三个不同设备通过浏览器发送的请求呢?
-
@progyammer 如果服务器有 3 个可用的 PHP 工作者,所有三个请求将同时执行。
标签: php asynchronous nonblocking