PHP Laravel - 如何将 Spatie Async 用于并发函数
Posted
技术标签:
【中文标题】PHP Laravel - 如何将 Spatie Async 用于并发函数【英文标题】:PHP Laravel - How to use Spatie Async for concurrent functions 【发布时间】:2021-10-23 06:04:35 【问题描述】:我正在尝试与spatie/async 并行运行一些功能,但遇到了一些麻烦。我设计了这个快速测试:
应该花费 37s 并输出 1 2 3 4
sleep(20); echo "<br> 1";
sleep(5); echo "<br> 2";
sleep(10); echo "<br> 3";
sleep(2); echo "<br> 4";
然后使用 spatie,这应该需要 20 秒并返回 4 2 3 1 但仍然需要 37s 并返回 1 2 3 4
$pool = Pool::create();
$pool
->add(function ()
sleep(20); echo "<br> 1";
)
->then(function ($output) )
->catch(function ($exception) )
->timeout(function () )
;
$pool
->add(function ()
sleep(5); echo "<br> 2";
)
->then(function ($output) )
->catch(function ($exception) )
->timeout(function () )
;
$pool->add(function ()
sleep(10); echo "<br> 3";
)
->then(function ($output) )
->catch(function ($exception) )
->timeout(function () )
;
$pool
->add(function ()
sleep(2); echo "<br> 4";
)
->then(function ($output) )
->catch(function ($exception) )
->timeout(function () )
;
await($pool);
【问题讨论】:
需要20s吗?它可能只是在最后合并每个进程的标准输出,而不是立即回显 @apokryfos - 不,还是 37 秒 做一个Pool::isSupported()
的var_dump来检查你是否可以运行异步操作
还有pthreads
和parallel
...它们确实有效,同时能够在较低级别进行编程。 spatie
可能依赖于某些模块,因为您所描述的是单个线程的行为,时间片。
【参考方案1】:
正如您在文档中看到的,
如果您当前的 php 运行时未安装所需的扩展(pcntl 和 posix),Pool 将自动回退到同步执行任务。
我高度怀疑你的环境就是这种情况,也就是说它只在主线程中运行。
但是,您还需要记住,并发并不意味着并行。
在单线程的情况下,它仍然可以实现并发,因为它本质上是执行任务之间的切换。但是,在给定时间只能有一个任务正在运行。
在您的示例中,sleep
函数本质上是 halts 主线程,因此即使您异步运行 4 个不同的任务也没关系,它仍然会占用所有任务的总睡眠时间( 37 s) 因为主线程需要等待那么长时间才能完成所有任务。
当您运行一些 CPU 密集型操作时,同样的情况也适用。在同一个线程中异步运行它的多个任务不会给你更快的执行速度,因为只有一个线程在任务之间切换。
【讨论】:
以上是关于PHP Laravel - 如何将 Spatie Async 用于并发函数的主要内容,如果未能解决你的问题,请参考以下文章
它是如何工作的 ?使用 Spatie/laravel-cronless-schedule 自定义的 Laravel 时间表
php Laravel上传Spatie Media Libary