请问在PHP或者webman中这类的耗时操作,如何优化?

aaoott

问题描述

我有5个for循环

for(...){
sleep(3)// 耗时结果
}
for(...){
sleep(5)// 耗时结果
}
for(...){
sleep(6)// 耗时结果
}
for(...){
sleep(7) // 耗时结果
}
for(...){
sleep(10) // 耗时结果
}

在c#中,我只需要开5个线程,然后等待全部完成,返回结果。总耗时10秒。
$result = waitAll();

// 需要返回上面的计算结果给response ,所以不能用队列之类的。

刚刚webman执行效率和开发效率不是一般的快,真是太NB了!!但是在PHP或者webman有什么好的方式能处理这类的需求吗?核心诉求是有没有办法能并发执行for,然后等待全部执行完毕,返回结果。

587 5 3
5个回答

胡桃
  • config/server.php
// ...
return [
    // ...
    'event_loop' => \Workerman\Events\Swoole::class,
    // ...
];

  • app/controller/Controller.php
<?php
declare(strict_types=1);

namespace app\controller;

use co;
use support\Request;

class Controller
{
    public function action(Request $request)
    {
        $cid_group[] = go(fn() => co::sleep(3));
        $cid_group[] = go(fn() => co::sleep(5));
        $cid_group[] = go(fn() => co::sleep(6));
        $cid_group[] = go(fn() => co::sleep(7));
        $cid_group[] = go(fn() => co::sleep(10));
        co::join($cid_group);
        // ...
    }
}
TM

可以放入队列里面然后等待完成后执行下面的业务?或者上swoole扩展开携程?

  • aaoott 2023-12-11

    队列可以等待吗?

  • TM 2023-12-11

    可以呀 也可以延迟队列

小W

多进程+channel

  • aaoott 2023-12-11

    我刚刚去看了一遍文档。还是不理解怎么弄

Mr_Deng

c#也来搞php了吗

  • 暂无评论
meows

C# 里面开多线程去做,php单线程就能完成这种并发请求。


  1. 安装swoole、openswoole扩展随便选择一个,具体用法:https://wiki.swoole.com/#/coroutine/wait_group?id=coroutinewaitgroup

    config/server.php
    // ...
    return [
    // ...
    'event_loop' => \Workerman\Events\Swoole::class,
    // ...
    ];
    /**
    也可以看看swoole 框架有没有好用的http-client工具库,这是其中一个:https://hyperf.wiki/3.1/#/zh-cn/guzzle (我没在workerman环境使用过,你自己亲测下)
    */
  2. 什么扩展都不安装,选择php.net的方式

// 初始化 cURL
$ch1 = curl_init('http://www.example.com/');
$ch2 = curl_init('http://www.example.org/');

// 创建 cURL 多个批处理句柄
$mh = curl_multi_init();
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

$active = null;

// 执行批处理
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

// 等待活动连接,直到有活动连接或超时
if ($mrc == CURLM_OK) {
    if (curl_multi_select($mh) == -1) {
        usleep(1);
    }
}

// 循环直到没有活动连接
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($active > 0);

// 关闭所有句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

3.选择guzzle/http库异步并发库,请查看 https://github.com/guzzle/guzzle (自行查询用法)

  • aaoott 2023-12-11

    谢谢!就是要这样的,我研究看看。不过我耗时并不是请求URL,如果不是IO密集型,是计算密集型的,单线程协程也能起到加速效果吗?

  • meows 2023-12-11

    协程主要是处理IO密集型,对于计算密集型还会降低些性能。(毕竟协程调度也是有开销的)

🔝