美文网首页
PHP 多进程处理任务

PHP 多进程处理任务

作者: guanguans | 来源:发表于2020-09-24 09:38 被阅读0次

PHP 多进程处理任务

pcntl 模块(非 Unix 类系统不支持此模块)

一个 PHP 多进程简单例子大概是这个样子:

// 5 个子进程处理任务
for ($i = 0; $i < 5; $i++) {
    $pid = pcntl_fork();
    if ($pid == -1) {
        die("could not fork");
    } elseif ($pid) {
        echo "I'm the Parent $i\n";
    } else { // 子进程处理
        echo "I'm the Child $i\n";
        // 业务处理
        exit($i); // 一定要注意退出子进程,否则 pcntl_fork() 会被子进程再 fork,带来处理上的影响。
    }
}

// 等待子进程执行结束
while (pcntl_waitpid(0, $status) != -1) {
    $status = pcntl_wexitstatus($status);
    echo "Child $status completed\n";
}

当然实际应用中我们不能够这样输出代码,不够健壮,也不够优雅,我所以找了个基于 pcntl 封装的扩展包来使用。

spatie/async - 基于 pcntl 封装的扩展包

以下是我使用 spatie/async 来优化一个多进程请求的例子

原代码(耗时 20s 左右)- https://github.com/guanguans/music-php/blob/v2.1.1/src/Music.php

原代码.png
/**
 * @param string $keyword
 *
 * @return array
 */
public function searchAll(string $keyword): array
{
    $songAll = [];

    foreach ($this->platforms as $platform) {
        $songAll = array_merge($songAll, $this->search($platform, $keyword));
    }

    return $songAll;
}

/**
 * @param string $platform
 * @param string $keyword
 *
 * @return mixed
 */
public function search(string $platform, string $keyword)
{
    $meting = $this->getMeting($platform);

    $songs = json_decode($meting->format()->search($keyword), true);

    foreach ($songs as $key => &$song) {
        $detail = json_decode($meting->format()->url($song['url_id']), true);
        if (empty($detail['url'])) {
            unset($songs[$key]);
        }
        $song = array_merge($song, $detail);
    }
    unset($song);

    return $songs;
}

改进后(耗时 4s 左右)- https://github.com/guanguans/music-php/blob/v2.1.2/src/Music.php

改进后.png
/**
 * @param string $keyword
 *
 * @return array
 */
public function searchAll(string $keyword): array
{
    $songAll = [];
    $pool = Pool::create();
    foreach ($this->platforms as $platform) {
        $pool->add(function () use ($platform, $keyword) {
            return $this->search($platform, $keyword);
        }, $this->getSerializedOutput())->then(function ($output) use (&$songAll) {
            $songAll = array_merge($songAll, $output);
        })->catch(function (\Throwable $exception) {
            exit($exception->getMessage());
        });
    }
    $pool->wait();

    return $songAll;
}

/**
 * @return mixed
 */
public function search(string $platform, string $keyword)
{
    $meting = $this->getMeting($platform);
    $songs = json_decode($meting->format()->search($keyword), true);

    $pool = Pool::create();
    foreach ($songs as $key => &$song) {
        $pool->add(function () use ($meting, $song) {
            return json_decode($meting->format()->url($song['url_id']), true);
        })->then(function ($output) use (&$songs, &$song, $key) {
            $song = array_merge($song, $output);
            if (empty($song['url'])) {
                unset($songs[$key]);
            }
        })->catch(function (\Throwable $exception) {
            exit($exception->getMessage());
        });
    }
    unset($song);
    $pool->wait();

    return $songs;
}

相关链接

原文链接

相关文章

  • PHP 多进程处理任务

    PHP 多进程处理任务 pcntl 模块(非 Unix 类系统不支持此模块) 一个 PHP 多进程简单例子大概是这...

  • PHP异步: 利用pcntl扩展实现PHP异步处理

    思路:利用pcntl生成一个子进程处理异步任务,处理完后杀掉子进程。依赖:该功能依赖于php pcntl扩展,使用...

  • [PHP] - 编译参数 --enable-pcntl

    官网:PHP - PCNTL 红框翻译 PHP进程控制支持 实现了类unix的进程创建、程序运行、消息处理、进程终...

  • PHP多进程处理并行处理任务实例

    本文目的 本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步。...

  • 【第53天】python全栈从入门到放弃

    1进程之间共享内存 2进程池的异步任务处理,返回1-10000之间的数字 3进程池的同步任务处理 4 多进程做任务...

  • php多进程实例总结

    多进程--fork 场景:日常任务中,有时需要通过php脚本执行一些日志分析,队列处理等任务,当数据量比较大时,可...

  • PHP 平滑重启原理

    重启命令 配置php.conf process_control_timeout是留给子进程处理来自master进程...

  • PHP 多进程处理

  • 协程实现原理

    [toc] 进程/线程/协程 背景 单任务处理:早期的计算机是什么样的, 卡带机? 真空管? 多任务处理系统: 多...

  • 网络素养

    第二章 专业名词 多任务处理 :多任务处理是指系统可同时运行多个进程,常用于电脑的操作系统。文中指的是人同时处理多...

网友评论

      本文标题:PHP 多进程处理任务

      本文链接:https://www.haomeiwen.com/subject/wjhzyktx.html