You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中并行执行内部函数?已尝试AMP及Swoole未果

在PHP中并行执行内部函数的可行方案

PHP里确实有多种方式实现函数的并行执行,针对你提到的AMP和Swoole使用失败的问题,下面附上经过验证的正确示例,同时提供其他可行方案:

1. 使用Swoole协程(推荐CLI/常驻进程场景)

Swoole的协程是轻量级并行方案,适合高性能场景。你之前没成功大概率是没正确处理协程间的结果同步,示例代码如下:

function a(){
    return 1;
}

function b(){
    return 2;
}

function c(){
    return 3;
}

function d(){
    return 4;
}

function E(){
    $response = [];
    $chan = new Swoole\Channel(4); // 创建容量为4的通道,用于协程间传递结果

    // 启动协程并行执行每个函数
    go(function() use ($chan) {
        $chan->push(['key' => 'a', 'value' => a()]);
    });
    go(function() use ($chan) {
        $chan->push(['key' => 'b', 'value' => b()]);
    });
    go(function() use ($chan) {
        $chan->push(['key' => 'c', 'value' => c()]);
    });
    go(function() use ($chan) {
        $chan->push(['key' => 'd', 'value' => d()]);
    });

    // 从通道中取出所有结果
    for ($i = 0; $i < 4; $i++) {
        $result = $chan->pop();
        $response[$result['key']] = $result['value'];
    }

    $chan->close();
    return $response;
}

// 执行并输出结果
var_dump(E());

通过go()创建独立协程执行每个函数,用Channel做协程间的通信,确保所有结果都被收集后再返回。

2. 使用AMP(异步并行编程框架)

AMP基于Promise实现异步并行,你之前失败可能是没正确使用Promise和await,正确示例如下:

首先确保已通过Composer安装AMP:composer require amphp/amp

require 'vendor/autoload.php';

use Amp\Promise;
use function Amp\async;
use function Amp\await;

function a(){
    return 1;
}

function b(){
    return 2;
}

function c(){
    return 3;
}

function d(){
    return 4;
}

function E(){
    // 用async包装每个函数,返回Promise对象
    $promises = [
        'a' => async(fn() => a()),
        'b' => async(fn() => b()),
        'c' => async(fn() => c()),
        'd' => async(fn() => d()),
    ];

    // 等待所有Promise完成,批量获取结果
    $response = await(Promise\all($promises));
    return $response;
}

// 执行并输出结果
var_dump(E());

async()会把同步函数包装成异步Promise,Promise\all()等待所有Promise完成后返回对应结果数组,顺序和传入的Promise数组一致。

3. 使用PCNTL多进程(仅CLI环境)

如果你的场景是CLI脚本,可以用PCNTL扩展创建多进程并行执行,示例:

function a(){
    return 1;
}

function b(){
    return 2;
}

function c(){
    return 3;
}

function d(){
    return 4;
}

function E(){
    $functions = [
        'a' => 'a',
        'b' => 'b',
        'c' => 'c',
        'd' => 'd',
    ];
    $pids = [];
    $response = [];
    $pipeHandles = [];

    foreach ($functions as $key => $func) {
        // 创建管道,用于子进程向父进程传递结果
        $pipe = [];
        pipe($pipe);
        $pid = pcntl_fork();

        if ($pid === -1) {
            die('创建进程失败');
        } elseif ($pid === 0) {
            // 子进程:执行函数,将结果写入管道后退出
            fclose($pipe[0]);
            $result = $func();
            fwrite($pipe[1], json_encode(['key' => $key, 'value' => $result]));
            fclose($pipe[1]);
            exit(0);
        } else {
            // 父进程:保存进程ID和管道读端
            $pids[] = $pid;
            $pipeHandles[$pid] = $pipe[0];
            fclose($pipe[1]);
        }
    }

    // 等待所有子进程结束,读取结果
    foreach ($pids as $pid) {
        pcntl_waitpid($pid, $status);
        $data = fread($pipeHandles[$pid], 1024);
        $result = json_decode($data, true);
        $response[$result['key']] = $result['value'];
        fclose($pipeHandles[$pid]);
    }

    return $response;
}

// 执行并输出结果
var_dump(E());

通过pcntl_fork()创建子进程,每个子进程执行一个函数,用管道传递结果给父进程,父进程等待所有子进程完成后收集结果。注意PCNTL扩展仅在CLI环境可用,web环境无法使用。

内容的提问来源于stack exchange,提问作者Buggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:31:26