channel仅限同进程内协程通信,跨进程须用ipc:pipe(默认半双工)或sysv消息队列;多worker可用swoole\process或process\manager(≥v4.5.3),均需主动回收子进程。

Channel 是协程间通信机制,不能用于进程间通信。Swoole 4 的多进程模型中,worker 进程彼此内存隔离,Channel 无法跨进程使用,它只在同一个进程内的协程之间有效。
进程间通信必须用 IPC 方式
Swoole 提供了两种原生支持的进程间通信(IPC)方式:
- Unix Socket 管道(Pipe):默认启用,父子/主从进程间最常用,半双工、同步阻塞(可设为非阻塞),适合简单指令或小数据传递
-
SysV 消息队列(Message Queue):需显式设置
$ipcType = SWOOLE_IPC_MSGQUEUE和$msgQueueKey,支持多进程并发读写,适合结构化任务分发
注意:Swoole\Coroutine\Channel 与 Swoole\Process 或 Swoole\Process\Manager 完全无关,混用会导致逻辑失效或静默失败。
创建多个 worker 进程的两种主流方式
根据场景选择合适封装层级:
-
直接使用
Swoole\Process:灵活控制每个子进程生命周期和通信方式
示例:启动 3 个独立 worker,主进程通过管道向其发送任务 -
使用
Swoole\Process\Manager(≥ v4.5.3):更简洁,支持批量添加 + 协程开关
示例:$pm->addBatch(4, function($pool, $id) { ... }, true)启动 4 个启用协程的 worker
两者都要求主进程调用 Process::wait() 或 $pm->start() 后主动回收子进程,避免僵尸进程。
实际通信示例(Pipe + 主从模式)
以下为主进程向子进程发送字符串、子进程回传处理结果的最小可行流程:
- 主进程创建子进程时传入回调函数,并保留
$process对象引用 - 子进程启动后立即调用
$worker->read()阻塞等待主进程写入 - 主进程调用
$process->write("hello"),子进程读到后处理并$worker->write("done") - 主进程再调用
$process->read()获取响应(注意:需确保读写顺序与管道方向一致)
若需多对多通信(如多个 worker 向主进程上报状态),建议改用消息队列,避免管道竞争或阻塞错位。
常见误区提醒
以下操作不会生效,务必规避:
- 在不同 worker 进程中 new 同一个 Channel 并期望共享数据 —— 每个进程的 Channel 完全独立
- 在
Swoole\Process\Manager的回调里使用go启动协程后,误以为该协程能访问其他 worker 的 Channel —— 仍属本进程协程空间 - 未检查 Swoole 版本就使用
Process\Manager—— v4.5.2 及以下会报Class not found
进程通信的关键是明确“谁写、谁读、走哪条路”,Channel 属于协程层,IPC 属于进程层,二者分属不同抽象层级,不可替代。











