PHP并发处理的三种高效解决方案
PHP 并发处理的三种常见且高效的并发处理手段:多进程(PCNTL)、多线程/多任务(Parallel 扩展)、协程/异步(Swoole)。每一部分都有完整的代码示例、ASCII 流程图和深入的原理说明,帮助你快速掌握 PHP 在不同场景下的并发实现方法。
一、并发处理的必要性与常见场景
在 Web 应用或脚本中,我们常会遇到如下需要并发处理的场景:
- 并行发起多个网络请求(如抓取多个第三方接口数据,批量爬虫)
 - 执行大量 I/O 密集型任务(如大批量文件读写、图像处理、数据库导入导出)
 - 后台任务队列消费(如将若干任务交给多进程或多线程并行处理,提高吞吐)
 - 长连接或异步任务(如 WebSocket、消息订阅、实时推送)
 
如果依赖传统的“串行”方式,一个一个地依次执行,就会导致等待时间累加、响应速度下降、CPU/IO 资源无法充分利用。通过并发(并行或异步)处理,可以显著提升脚本整体吞吐,并降低单次操作的总耗时。
在 PHP 领域,常见的三种并发思路是:
- 多进程(Process):通过 
pcntl_fork()创建子进程,各自独立执行任务,适合计算与 I/O 混合型场景。 - 多线程/多任务(Thread/Task):使用 
parallel或pthreads扩展,在同一进程内启动多个执行环境,适合轻量计算与共享内存场景。 - 协程/异步(Coroutine/Async):以 Swoole 为代表,通过协程或事件循环驱动单进程并发,极大降低上下文切换开销,适合大并发 I/O 场景。
 
下面我们依次详细介绍这三种并发手段,给出代码示例、ASCII 图解与性能要点。
二、方案一:多进程 —— 使用 PCNTL 扩展
2.1 基本原理
- 概念:在 Unix-like 系统(Linux、macOS)中,进程(Process)是操作系统分配资源的基本单位。通过调用 
pcntl_fork(),父进程会复制出一个子进程,两者从 fork 点开始各自独立运行。 优势:
- 资源隔离:父子进程各自拥有独立的内存空间,互不干扰,适合运行耗时耗内存的任务。
 - 稳定可靠:某个子进程 crash 不会直接影响父进程或其他子进程。
 - 利用多核:在多核 CPU 上,多个进程可并行调度,提高计算与 I/O 并行度。
 
劣势:
- 内存开销大:每个子进程都会复制父进程的内存页,fork 时会产生写时复制(Copy-on-Write)。
 - 上下文切换成本:系统调度多进程会带来一定开销,频繁 fork/exit 会影响效率。
 - 开发复杂度高:需要手动回收子进程、避免僵尸进程,并处理进程间通信(若有需求)。
 
2.2 环境准备
- 确保 PHP 编译时开启了 
--enable-pcntl(多数 Linux 包管理器自带支持)。 - CLI 模式下运行。Web 环境(Apache/Nginx+PHP-FPM)通常不允许 
pcntl_fork(),需要从命令行执行脚本。 - PHP 7+ 建议版本,语法与功能更完善。
 
2.3 简单示例:并行执行多个任务
下面示例演示如何利用 pcntl_fork() 启动多个子进程并行执行任务(如访问 URL、处理数据),并在父进程中等待所有子进程结束。
<?php
// 文件:multi_process.php
// 要并行执行的“任务”:简单模拟网络请求或耗时计算
function doTask(int $taskId) {
    echo "[子进程 {$taskId}] 开始任务,PID=" . getmypid() . "\n";
    // 模拟耗时:随机 sleep 1~3 秒
    $sleep = rand(1, 3);
    sleep($sleep);
    echo "[子进程 {$taskId}] 任务完成,用时 {$sleep} 秒\n";
}
// 任务数量(子进程数)
// 建议不要超过 CPU 核心数的 2 倍,否则上下文切换开销可能增大
$taskCount = 5;
$childPids = [];
// 父进程循环 fork
for ($i = 1; $i <= $taskCount; $i++) {
    $pid = pcntl_fork();
    if ($pid === -1) {
        // fork 失败
        die("无法 fork 子进程 #{$i}\n");
    } elseif ($pid === 0) {
        // 子进程分支
        doTask($i);
        // 子进程必须 exit,否则会继续执行父进程后续代码
        exit(0);
    } else {
        // 父进程分支:记录子进程 PID,继续循环创建下一子进程
        $childPids[] = $pid;
    }
}
// 父进程:等待所有子进程完成
echo "[父进程] 等待子进程完成...\n";
foreach ($childPids as $pid) {
    // pcntl_waitpid() 阻塞等待指定子进程结束
    pcntl_waitpid($pid, $status);
    echo "[父进程] 子进程 PID={$pid} 已结束,状态={$status}\n";
}
echo "[父进程] 所有子进程已完成,退出。\n";运行方式
php multi_process.phpASCII 流程图
┌─────────────────────────────────────────────────────────┐
│                      父进程 (PID = 1000)                │
└─────────────────────────────────────────────────────────┘
                        │
                        │ pcntl_fork() 创建子进程 1 (PID=1001)
                        ↓
┌─────────────────┐    ┌─────────────────┐
│ 父进程 继续循环 │    │ 子进程 1 执行 doTask(1) │
│ (记录 PID=1001) │    │                  │
└─────────────────┘    └─────────────────┘
   │                            │
   │ pcntl_fork() 创建子进程 2   │
   ↓                            ↓
┌─────────────────┐      ┌────────────────────┐
│ 父进程 继续循环 │      │ 子进程 2 执行 doTask(2) │
│ (记录 PID=1002) │      │                    │
└─────────────────┘      └────────────────────┘
   │                            │
   ⋮                            ⋮
   │                            │
   │ pcntl_fork() 创建子进程 5   │
   ↓                            ↓
┌─────────────────┐      ┌────────────────────┐
│ 父进程 循环结束 │      │ 子进程 5 执行 doTask(5) │
│ (记录 PID=1005) │      │                    │
└─────────────────┘      └────────────────────┘
   │                            │
   │ 父进程调用 pcntl_waitpid() 等待各子进程结束
   └─────────────────────────────────────────────────>
                            │
            ┌───────────────────────────────────────┐
            │ 子进程各自执行完 doTask() 后 exit(0)  │
            └───────────────────────────────────────┘
                            ↓
                父进程输出“子进程 PID 已结束”消息
                            ↓
                 父进程等待完毕后退出脚本解析与要点
pcntl_fork():返回值- 在父进程中,返回子进程的 PID(>0)
 - 在子进程中,返回 0
 - 失败时,返回 -1
 
- 子进程执行完毕后必须 
exit(0),否则子进程会继续执行父进程后续代码,导致进程混淆。 - 父进程通过 
pcntl_waitpid($pid, $status)阻塞等待指定子进程结束,并获取退出状态。 - 最好将任务量与 CPU 核心数做简要衡量,避免创建过多子进程带来过大上下文切换成本。
 
三、方案二:多线程/多任务 —— 使用 Parallel 扩展
注意:PHP 官方不再维护pthreads扩展,且仅支持 CLI ZTS(线程安全)版。更推荐使用 PHP 7.4+ 的 Parallel 扩展,能在 CLI 下创建“并行运行环境(Runtime)”,每个Runtime都是独立的线程环境,可以运行\parallel\Future任务。
3.1 基本原理
- Parallel 扩展:为 PHP 提供了一套纯 PHP 层的并行处理 API,通过 
parallel\Runtime在后台启动一个线程环境,每个环境会有自己独立的上下文,可以运行指定的函数或脚本。 优势:
- 内存隔离:与 pcntl 类似,
Runtime内的代码有自己独立内存,不会与主线程直接共享变量,避免竞争。 - API 友好:更类似“线程池+任务队列”模型,提交任务后可异步获取结果。
 - 无需 ZTS:Parallel 扩展无需编译成 ZTS 版本的 PHP,即可使用。
 
- 内存隔离:与 pcntl 类似,
 劣势:
- 环境要求:仅支持 PHP 7.2+,且需先通过 
pecl install parallel安装扩展。 - 内存开销:每个 
Runtime会在后台生成一个线程及其上下文,资源消耗不可忽视。 - 不支持 Web 环境:仅能在 CLI 下运行。
 
- 环境要求:仅支持 PHP 7.2+,且需先通过 
 
3.2 安装与检查
# 安装 Parallel 扩展
pecl install parallel
# 确保 php.ini 中已加载 parallel.so
echo "extension=parallel.so" >> /etc/php/7.4/cli/php.ini
# 验证
php -m | grep parallel
# 如果输出 parallel 则说明安装成功3.3 简单示例:并行执行多个函数
以下示例演示如何使用 parallel\Runtime 和 Future 并行执行多个耗时函数,并在主线程中等待所有结果。
<?php
// 文件:parallel_example.php
use parallel\Runtime;
use parallel\Future;
// 自动加载如果使用 Composer,可根据实际情况调整
// require 'vendor/autoload.php';
// 模拟耗时函数:睡眠 1~3 秒
function taskFunction(int $taskId): string {
    echo "[Thread {$taskId}] 开始任务,TID=" . getmypid() . "\n";
    $sleep = rand(1, 3);
    sleep($sleep);
    return "[Thread {$taskId}] 完成任务,用时 {$sleep} 秒";
}
$taskCount = 5;
$runtimes = [];
$futures = [];
// 1. 创建多个 Runtime(相当于线程环境)
for ($i = 1; $i <= $taskCount; $i++) {
    $runtimes[$i] = new Runtime(); // 新建线程环境
}
// 2. 向各 Runtime 提交任务
for ($i = 1; $i <= $taskCount; $i++) {
    // run() 返回 Future 对象,可通过 Future->value() 获取执行结果(阻塞)
    $futures[$i] = $runtimes[$i]->run(function(int $tid) {
        return taskFunction($tid);
    }, [$i]);
}
// 3. 主线程等待并获取所有结果
foreach ($futures as $i => $future) {
    $result = $future->value(); // 阻塞到对应任务完成
    echo $result . "\n";
}
// 4. 关闭线程环境(可选,PHP 会在脚本结束时自动回收)
foreach ($runtimes as $rt) {
    $rt->close();
}
echo "[主线程] 所有并行任务已完成,退出。\n";运行方式
php parallel_example.phpASCII 流程图
┌──────────────────────────────────────────────────────┐
│                    主线程 (PID=2000)                │
└──────────────────────────────────────────────────────┘
     │           │           │           │           │
     │           │           │           │           │
     ▼           ▼           ▼           ▼           ▼
┌────────┐  ┌────────┐  ┌────────┐  ┌────────┐  ┌────────┐
│Runtime1│  │Runtime2│  │Runtime3│  │Runtime4│  │Runtime5│   <- 每个都是一个独立线程环境
│ (TID)  │  │ (TID)  │  │ (TID)  │  │ (TID)  │  │ (TID)  │
└───┬────┘  └───┬────┘  └───┬────┘  └───┬────┘  └───┬────┘
    │             │            │             │           │
    │ 提交任务     │ 提交任务     │ 提交任务      │ 提交任务    │ 提交任务
    ▼             ▼            ▼             ▼           ▼
[Thread1]     [Thread2]     [Thread3]     [Thread4]   [Thread5]
 doTask(1)    doTask(2)    doTask(3)    doTask(4)  doTask(5)
    │             │            │             │          │
    └─────┬───────┴──┬─────────┴──┬───────────┴───┬──────┘
          ▼          ▼           ▼               ▼
   主线程等待 future->value()   ...         Collect Results解析与要点
new Runtime():为每个并行任务创建一个新的“线程环境”,内部会复制(序列化再反序列化)全局依赖。- 闭包函数传参:
run(function, [args])中,闭包与传入参数会被序列化并发送到对应 Runtime 环境。 Future->value():阻塞等待目标线程返回执行结果。若当前 Future 已完成则立即返回。- 资源隔离:在闭包内部定义的函数 
taskFunction是通过序列化传给线程,并在新环境内执行,主线程无法直接访问线程内部变量。 - 关闭线程:可通过 
$runtime->close()将线程环境释放,但脚本结束时会自动回收,无需手动关闭也可。 
四、方案三:协程/异步 —— 使用 Swoole 扩展
4.1 基本原理
- Swoole:一个为 PHP 提供高性能网络通信、异步 I/O、协程等功能的扩展。通过协程(Coroutine)机制,让 PHP 在单进程内实现类似“多线程”的并发效果。
 - 协程:相比传统“线程”更轻量,切换时无需系统调度,几乎没有上下文切换成本。
 优势:
- 高并发 I/O 性能:适合高并发网络请求、长连接、WebSocket 等场景。
 - 简单语法:使用 
go(function() { … })即可创建协程,在协程内部可以像写同步代码一样写异步逻辑。 - 丰富生态:Swoole 内置 HTTP Server、WebSocket Server、定时器、Channel 等并发构建块。
 
劣势:
- 需要安装扩展:需先 
pecl install swoole或自行编译安装。 - 不适合全栈同步框架:若项目大量依赖同步阻塞式代码,需要做协程安全改造。
 - 需使用 CLI 方式运行:不能像普通 PHP-FPM 一样被 Nginx 调用。
 
- 需要安装扩展:需先 
 
4.2 安装与检查
# 安装 Swoole 最新稳定版本
pecl install swoole
# 确保 php.ini 中已加载 swoole.so
echo "extension=swoole.so" >> /etc/php/7.4/cli/php.ini
# 验证
php --ri swoole
# 会显示 Swoole 版本与配置信息4.3 示例一:协程并行发起多 HTTP 请求
下面示例展示如何通过 Swoole 协程并发地发起多个 HTTP GET 请求,并在所有请求完成后收集响应。
<?php
// 文件:swoole_coro_http.php
use Swoole\Coroutine\Http\Client;
use Swoole\Coroutine;
// 要并行请求的 URL 列表
$urls = [
    'http://httpbin.org/delay/2', // 延迟 2 秒返回
    'http://httpbin.org/delay/1',
    'http://httpbin.org/status/200',
    'http://httpbin.org/uuid',
    'http://httpbin.org/get'
];
// 协程入口
Co\run(function() use ($urls) {
    $responses = [];
    $wg = new Swoole\Coroutine\WaitGroup();
    foreach ($urls as $index => $url) {
        $wg->add(); // 增加等待组计数
        go(function() use ($index, $url, &$responses, $wg) {
            $parsed = parse_url($url);
            $host = $parsed['host'];
            $port = ($parsed['scheme'] === 'https') ? 443 : 80;
            $path = $parsed['path'] . (isset($parsed['query']) ? "?{$parsed['query']}" : '');
            $cli = new Client($host, $port, $parsed['scheme'] === 'https');
            $cli->set(['timeout' => 5]);
            $cli->get($path);
            $body = $cli->body;
            $status = $cli->statusCode;
            $cli->close();
            $responses[$index] = [
                'url'    => $url,
                'status' => $status,
                'body'   => substr($body, 0, 100) . '…' // 为示例只截取前100字符
            ];
            echo "[协程 {$index}] 请求 {$url} 完成,状态码={$status}\n";
            $wg->done(); // 通知 WaitGroup 当前协程已完成
        });
    }
    // 等待所有协程执行完毕
    $wg->wait();
    echo "[主协程] 所有请求已完成,共 " . count($responses) . " 条响应。\n";
    print_r($responses);
});运行方式
php swoole_coro_http.phpASCII 流程图
┌───────────────────────────────────────────────────────────────────┐
│                      主协程 (Main Coroutine)                     │
└───────────────────────────────────────────────────────────────────┘
          │             │              │              │              │
      go()【】       go()【】        go()【】        go()【】        go()【】
          │             │              │              │              │
          ▼             ▼              ▼              ▼              ▼
 [协程 0]         [协程 1]        [协程 2]         [协程 3]       [协程 4]
  send GET       send GET         send GET         send GET       send GET
  await I/O      await I/O        await I/O        await I/O      await I/O
    ↑               ↑               ↑               ↑             ↑
   I/O 完成       I/O 完成        I/O 完成        I/O 完成       I/O 完成
    │               │               │               │             │
  异步返回        异步返回         异步返回        异步返回      异步返回
    │               │               │              │             │
  协程 0                               …                            协程 4
  写入 $responses                              …                      写入 $responses
  $wg->done()                                    …                      $wg->done()
    │               │               │              │             │
┌───────────────────────────────────────────────────────────────────┐
│ 主协程调用 $wg->wait() 阻塞,直到所有 $wg->done() 都执行完成        │
└───────────────────────────────────────────────────────────────────┘
                           ↓
┌───────────────────────────────────────────────────────────────────┐
│       打印所有并行请求结果并退出脚本                             │
└───────────────────────────────────────────────────────────────────┘解析与要点
\Swoole\Coroutine\run():启动一个全新的协程容器环境,主协程会在回调内部启动。go(function() { … }):创建并切换到一个新协程执行闭包函数。Swoole\Coroutine\Http\Client:已被协程化的 HTTP 客户端,可在协程中非阻塞地进行网络请求。WaitGroup:相当于 Go 语言的 WaitGroup,用于等待多个协程都调用$wg->done(),再从$wg->wait()的阻塞中继续执行。- 单进程多协程:所有协程都跑在同一个系统进程中,不会像多进程/多线程那样切换内核调度,协程的上下文切换几乎没有开销。
 
4.4 示例二:使用 Swoole Process 实现多进程任务处理
如果项目无法全部迁移到协程模式,也可以使用 Swoole 提供的 Process 类来创建多进程,并结合管道/消息队列等在进程间通信。
以下示例演示如何用 Swoole Process 创建 3 个子进程并行执行任务,并在父进程中通过管道收集结果。
<?php
// 文件:swoole_process.php
use Swoole\Process;
// 要并行执行的耗时函数
function doJob(int $jobId) {
    echo "[子进程 {$jobId}] (PID=" . getmypid() . ") 开始任务\n";
    $sleep = rand(1, 3);
    sleep($sleep);
    $result = "[子进程 {$jobId}] 任务完成,用时 {$sleep} 秒";
    return $result;
}
$processCount = 3;
$childProcesses = [];
// 父进程创建多个 Swoole\Process
for ($i = 1; $i <= $processCount; $i++) {
    // 1. 定义子进程回调,使用匿名函数捕获 $i 作为任务编号
    $process = new Process(function(Process $worker) use ($i) {
        // 子进程内部执行
        $result = doJob($i);
        // 将结果写入管道,父进程可读取
        $worker->write($result);
        // 退出子进程
        $worker->exit(0);
    }, true, SOCK_DGRAM); // 启用管道
    $pid = $process->start();
    $childProcesses[$i] = ['pid' => $pid, 'pipe' => $process];
}
// 父进程:等待并读取子进程通过管道写入的数据
foreach ($childProcesses as $i => $info) {
    $pipe = $info['pipe'];
    // 阻塞读取子进程写入管道的数据
    $data = $pipe->read();
    echo "[父进程] 收到子进程 {$i} 结果:{$data}\n";
    // 等待子进程退出,避免僵尸进程
    Process::wait(true);
}
echo "[父进程] 所有子进程处理完成,退出。\n";运行方式
php swoole_process.phpASCII 流程图
┌──────────────────────────────────────────────────────────┐
│                      父进程 (PID=3000)                   │
└──────────────────────────────────────────────────────────┘
       │            │            │
       │            │            │
       ▼            ▼            ▼
┌────────┐    ┌────────┐    ┌────────┐
│Proc #1 │    │Proc #2 │    │Proc #3 │
│(PID)   │    │(PID)   │    │(PID)   │
└───┬────┘    └───┬────┘    └───┬────┘
    │             │             │
    │ doJob(1)    │ doJob(2)    │ doJob(3)
    │             │             │
    │ write “结果” │ write “结果” │ write “结果”
    ▼             ▼             ▼
 父进程从管道中    父进程从管道中   父进程从管道中
  读到结果 1       读到结果 2      读到结果 3
    │             │             │
    └─────────────┴─────────────┘
                   │
       父进程调用 Process::wait() 回收子进程
                   ↓
        父进程输出“所有子进程完成”后退出解析与要点
new Process(callable, true, SOCK_DGRAM):第二个参数true表示启用管道通信;第三个参数指定管道类型(SOCK_DGRAM或SOCK_STREAM)。- 子进程写入管道:调用 
$worker->write($data),父进程通过$process->read()获取数据。 - 父进程回收子进程:使用 
Process::wait()(或Process::wait(true))等待任意子进程退出,并避免产生僵尸进程。 - Swoole Process 与 PCNTL 的区别:前者封装更完善,有更方便的进程管理 API,但本质依然是多进程模型。
 
五、三种方案对比与选型建议
| 特性 / 方案 | 多进程(PCNTL) | 多线程/多任务(Parallel) | 协程/异步(Swoole) | 
|---|---|---|---|
| 并发模型 | 操作系统原生进程 | PHP 用户态线程环境 | 协程(用户态调度,单进程) | 
| 安装与启用 | PHP CLI + pcntl 扩展 | PHP 7.2+ + parallel 扩展 | PHP 7.x + swoole 扩展 | 
| 内存开销 | 每个子进程复制父进程内存(COW) | 每个 Runtime 启动独立线程,需复制上下文 | 单进程内协程切换,无额外线程上下文 | 
| 上下文切换开销 | 较高(内核调度) | 较高(线程调度) | 非常低(协程切换由 Swoole 管理) | 
| 平台兼容性 | 仅 CLI(Unix-like) | 仅 CLI(PHP 7.2+) | 仅 CLI(Unix-like/Windows,都支持) | 
| 编程复杂度 | 中等(手动 fork/wait、IPC) | 低(类似线程池、Future 模式) | 低(异步写法接近同步,可用 channel、WaitGroup) | 
| 适用场景 | 计算密集型、多核利用;进程隔离 | 中小规模并行计算;任务隔离 | 高并发 I/O;网络爬虫;实时通信 | 
| 数据共享 | 进程间需通过管道/消息队列等 IPC | 线程间需序列化数据到 Runtime | 协程可共享全局变量(需注意同步) | 
| 稳定性 | 高:一个子进程崩溃不影响父进程 | 较高:线程隔离度不如进程,但 Runtime 崩溃会影响父 | 高:协程内抛异常可捕获,单进程风险较低 | 
5.1 选型建议
纯 CPU 密集型任务(如数据批量计算、图像处理):
- 建议使用 多进程(PCNTL),能够充分利用多核 CPU,且进程间隔离性好。
 
分布式任务调度、轻量并行计算(如同时处理多个独立小任务):
- 可以考虑 Parallel 扩展,API 更简单,适合 PHP 内部任务并行。
 
大量并发网络请求、I/O 密集型场景(如批量爬虫、聊天室、长连接服务):
- 强烈推荐 Swoole 协程,其异步 I/O 性能远超多进程/多线程,并发量可达数万级别。
 
小型脚本并发需求(如定时脚本并行处理少量任务,不想引入复杂扩展):
- 使用 PCNTL 即可,开发成本低,无需额外安装第三方扩展。
 
六、常见问题与注意事项
PCNTL 进程数过多导致内存耗尽
- 在多进程模式下,若一次性 fork 过多子进程(如上百个),会瞬间占用大量内存,可能触发 OOM。
 - 建议按 CPU 核心数设定进程数,或按业务量使用固定大小的进程池,并用队列控制任务分发。
 
Parallel 运行时环境上下文传递限制
- Parallel 会序列化全局变量与闭包,若闭包中捕获了不可序列化资源(如数据库连接、Socket),会导致失败。
 - 最好将要执行的代码与其依赖的类、函数文件放在同一脚本中,或先在 Runtime 内重新加载依赖。
 
Swoole 协程中不可使用阻塞 I/O
- 在协程中必须使用 Swoole 提供的协程化 I/O(如 
Co\MySQL\、Co\Http\Client)或 PHP 原生的非阻塞流程(如file_get_contents会阻塞整个进程)。 - 若使用阻塞 I/O,整个进程会被挂起,丧失协程并发优势。
 
- 在协程中必须使用 Swoole 提供的协程化 I/O(如 
 进程/协程内错误处理
- 子进程/子协程内发生致命错误不会直接中断父进程,但需要在父进程中捕获(如 PCNTL 的 
pcntl_signal(SIGCHLD, ...)或 Swoole 协程模式下的 try/catch)。 - 建议在子进程或协程内部加上异常捕获,并在写入管道或 Future 返回错误信息,以便父进程统一处理。
 
- 子进程/子协程内发生致命错误不会直接中断父进程,但需要在父进程中捕获(如 PCNTL 的 
 跨平台兼容性
- PCNTL 仅在 Linux/macOS 环境可用,Windows 不支持。
 - Parallel 在 Windows、Linux 都可用,但需要 PECL 安装。
 - Swoole 支持多平台,Windows 下也可正常编译与运行,但需使用对应的 DLL 文件。
 
七、总结
本文系统地介绍了 PHP 并发处理的三种高效解决方案:
多进程(PCNTL)
- 通过 
pcntl_fork()启动子进程并行运行任务,适合计算密集型或需要进程隔离的场景。 - 示例中演示了如何 fork 五个子进程并 parallel 执行固定任务,并通过 
pcntl_waitpid()等待子进程结束。 
- 通过 
 多线程/多任务(Parallel 扩展)
- 利用 
parallel\Runtime创建线程环境并提交闭包任务,以Future->value()等待结果,适合中小规模并行任务。 - 相比 PCNTL 更易管理,API 友好,但仍需在 CLI 环境下运行,且需先安装 
parallel扩展。 
- 利用 
 协程/异步(Swoole 扩展)
- 以协程为基础,在单进程内实现高并发 I/O 操作。示例演示了协程并行发起多 HTTP 请求,使用 
WaitGroup整合结果,适合高并发网络场景。 - Swoole 还提供 
Process类,可用于多进程管理。 
- 以协程为基础,在单进程内实现高并发 I/O 操作。示例演示了协程并行发起多 HTTP 请求,使用 
 
最后,结合不同场景与业务需求,进行合理选型:
- CPU 密集型:优先 PCNTL 多进程。
 - 轻量并行:优先 Parallel 多任务。
 - 高并发 I/O:优先 Swoole 协程异步。
 
评论已关闭