我有一个PHP脚本,它将从多个REST下载的数据处理为标准化格式,并构建该数据的数组或表。脚本当前同步执行所有内容,因此花费的时间太长。
我一直试图学习如何执行同时或异步地获取和处理数据的函数,以便总时间是最慢调用的时间。从我的研究来看,ReactPHP或Amp是正确的工具。
但是,我在创建实际正确执行的测试代码方面没有成功。附加了一个简单的示例,mysquare()表示我的更复杂的函数。由于网络上缺少我想要实现的目标的例子,我被迫使用了一个蛮力方法,我的代码中列出了3个例子。
Q1:我在工作中使用了正确的工具吗?
Q2:您能修复我的示例代码以异步执行吗?
注:我是一个真正的初学者,所以最简单的代码示例与最低水平的高级编程术语将不胜感激。
<?php
require_once("../vendor/autoload.php");
for ($i = 0; $i <= 4; $i++) {
// Experiment 1
$deferred[$i] = new React\Promise\Deferred(function () use ($i) {
echo $x."\n";
usleep(rand(0, 3000000)); // Simulates long network call
return array($x=> $x * $x);
});
// Experiment 2
$promise[$i]=$deferred[$i]->promise(function () use ($i) {
echo $x."\n";
usleep(rand(0, 3000000)); // Simulates long network call
return array($x=> $x * $x);
});
// Experiment 3
$functioncall[$i] = function () use ($i) {
echo $x."\n";
usleep(rand(0, 3000000)); // Simulates long network call
return array($x=> $x * $x);
};
}
$promises = React\Promise\all($deferred); // Doesn't work
$promises = React\Promise\all($promise); // Doesn't work
$promises = React\Promise\all($functioncall); // Doesn't work
// print_r($promises); // Doesn't return array of results but a complex object
// This is what I would like to execute simulatenously with a variety of inputs
function mysquare($x)
{
echo $x."\n";
usleep(rand(0, 3000000)); // Simulates long network call
return array($x=> $x * $x);
}发布于 2018-07-13 01:29:51
异步并不意味着多个线程并行执行。只有当函数(例如)执行IO (例如HTTP请求)时,才能真正在“同一时间”运行。
我们阻塞了睡眠,所以你什么也得不到。ReactPHP和Amp本身都将有某种“睡眠”功能,这是在事件循环中内置的。
出于同样的原因,您将不能只使用卷发,因为它也会被挡出方框。您需要使用反应和放大器提供和/推荐的HTTP库。
因为您的最终目标只是执行HTTP请求,所以您也不能使用这些框架中的任何一个,而只使用curl_multi函数。不过,它们有点难用。
发布于 2018-07-16 00:37:09
我回答自己的问题是为了帮助其他用户,但是这个解决方案是单独开发的,没有经验丰富的程序员的帮助,所以我不知道这最终是否是最好的方法。
TL;DR
我从ReactPHP转到使用amphp/parallel-functions,它提供了简化的终端用户界面.使用此接口附加的示例代码。
<?php
require_once("../vendor/autoload.php");
use function Amp\ParallelFunctions\parallelMap;
use function Amp\Promise\wait;
$start = \microtime(true);
$mysquare = function ($x) {
sleep($x); // Simulates long network call
//echo $x."\n";
return $x * $x;
};
print_r(wait(parallelMap([5,4,3,2,1,6,7,8,9,10], $mysquare)));
print 'Took ' . (\microtime(true) - $start) . ' milliseconds.' . \PHP_EOL;示例代码在10.2秒内执行,比运行时间最长的$mysquare()实例略长。
在我的实际用例中,我能够在大约5秒内通过HTTP从90个不同的源获取数据。
备注:
amphp/parallel-functions库似乎在使用遮罩下的线程。从我的初步经验来看,这似乎需要更多的内存,而不仅仅是一个线程PHP脚本,但我还没有完全确定它的影响。当我通过"use ($myarray)“表达式将一个大数组传递给$myarray时突出显示了这一点,数组为65 to。这使代码陷入停顿,使执行时间成倍增加,以至于花费的时间比同步执行要长几个数量级。此外,内存使用高峰在5G以上!在某种程度上,这让我相信amphp是在复制每个实例的$myarray。修改我的代码以避免"use ($myarray)“表达式解决了这个问题。
https://stackoverflow.com/questions/51316407
复制相似问题