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 左右)- github.com/guanguans/m…

原代码

/** * @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 左右)- github.com/guanguans/m…

改进后

/** * @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培训栏目!

更多相关文章

  1. 教你使用spatie/async库来写异步的PHP代码
  2. PHP模拟supervisor的进程管理
  3. 如何下载php开源代码
  4. PHP多进程、信号量及孤儿进程和僵尸进程
  5. PHP 代码优化 技巧总结
  6. PHP 实现守护进程

随机推荐

  1. Android M PackageManagerService解析
  2. android的ant脚本自动生成模板
  3. Android Studio 插件(二)
  4. android&&ScaleType android:scaleType="
  5. Android最好看的圆形进度条ProgressBar
  6. 【Android】App界面与顶部状态栏重叠遮盖
  7. Android设备重启(reboot)---Android stud
  8. Andriod开发之浏览器开发(WebView)
  9. ADT Bundle最后一次更新的版本下载地址
  10. Layouts与Views