Swoole Task任务默认单向,结果回传需用taskwait()同步等待或onFinish回调+任务ID关联;协程中可用Channel实现伪同步,注意数据序列化与大小限制。

Swoole 的 Task 任务默认是“单向”的:Worker 投递任务给 Task 进程后,不等待结果,继续执行。若需 Task 执行完后把结果返回给 Worker,不能靠投递时直接获取返回值(因为是异步非阻塞),而要通过 回调机制 + 任务 ID 关联 实现结果回传。
用 taskwait() 同步等待(适合短耗时、可接受阻塞的场景)
如果 Worker 能容忍短暂阻塞(比如任务执行在几十毫秒内),可直接用 $server->taskwait()。它会同步等待 Task 执行完成并返回结果,底层自动处理进程通信和超时控制。
- 调用后 Worker 线程会挂起,直到 Task 返回或超时
- 返回值就是 Task 中
return或exit()的内容(支持数组、字符串、数字等可序列化类型) - 超时时间单位为秒,建议设为合理值(如 1.5),避免卡死
示例:
<?php$result = $server->taskwait(['cmd' => 'send_email', 'to' => 'a@b.com'], 1.5);
if ($result === false) {
// 超时或 Task 进程异常
} else {
// $result 是 Task 中 return 的值,如 ['status' => 'success']
}
?>
用 onFinish 回调 + 任务 ID 关联(推荐用于真正异步场景)
当 Worker 必须保持高并发、不能阻塞时,应使用 $server->task() 投递 + onFinish 回调。Task 执行完毕后,Swoole 主动通知 Worker,但需你自己在投递前记录上下文(比如请求 ID、协程 ID 或 closure 引用),让回调能“找到”对应的处理逻辑。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 在投递前生成唯一任务 ID(可用
swoole_microtime()+ 进程 ID,或用coroutine::getuid()如果在协程中) - 把任务 ID 和待执行的回调函数(如 Closure)存入内存表(如
swoole_table)或全局数组(注意多协程安全) - 在
onFinish中根据 $taskId 查到对应回调,并执行 - 务必清理已触发的回调,防止内存泄漏
关键点:Swoole 的 $taskId 在一次 task 投递中是唯一且稳定的,可在 Worker 和 Task 进程间传递,是关联结果的核心凭证。
进阶:用 Channel 或协程调度实现“伪同步”
在协程环境中(如 Swoole 4.4+ 配合 go + chan),可创建一个 Channel,在投递任务后立即 recv() 等待;Task 执行完后把结果 push 到该 Channel。这样 Worker 表面是“等待”,实际不阻塞线程,仍保持协程并发能力。
- 每个任务配一个独立 Channel,避免混淆
- Channel 需设置超时(
recv(1.5)),防止永远挂起 - 适用于协程风格编码,对传统回调逻辑改造较大
注意事项与避坑
Task 进程无法直接访问 Worker 进程的变量或对象实例(IPC 隔离),所有数据必须显式序列化传递;返回值大小建议控制在 2MB 内,过大可能触发警告或失败;onFinish 回调运行在 Worker 进程,不是 Task 进程,所以可安全操作连接池、数据库句柄等 Worker 资源。

















