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来检查你是否可以运行异步操作 还有pthreadsparallel ...它们确实有效,同时能够在较低级别进行编程。 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

php Laravel Spatie获得特定角色的用户

php Spatie Laravel Model状态范围具有状态

php Laravel Spatie更新用户和同步用户角色

php 具有Spatie Peermission包的Laravel Nova用户模型