swoole协程cpu密集场景需启用抢占式调度:先调用swoole\runtime::enablecoroutine(true),再通过swoole\coroutine::set(['max_exec_msec' => 5])设置超时阈值,要求php≥7.4且swoole≥4.4.0;也可卸载任务至task进程或在循环中插入co::usleep(1)主动让出。

当Swoole协程中执行大量循环计算、加密解密、图像处理等CPU密集型操作时,协程不会主动让出控制权,导致其他协程长期得不到调度,请求堆积超时甚至服务不可用。
启用协程抢占式调度
第一步:在Swoole服务器启动前,调用Swoole\Runtime::enableCoroutine(true)开启协程化运行时。
第二步:设置抢占式调度阈值,执行Swoole\Coroutine::set(['max_exec_msec' => 5]),表示单个协程连续CPU执行超过5毫秒即被强制让出。
第三步:确保PHP版本≥7.4且Swoole版本≥4.4.0,否则max_exec_msec参数将被忽略,调度仍为纯IO驱动。
注意:【max_exec_msec必须在Server::start()之前设置,启动后修改无效】。该值不宜设得过小(如≤1),否则频繁切换会增加调度开销;也不宜过大(如≥20),起不到均衡效果。
将CPU密集任务卸载到Task进程
方法一:使用$server->task()投递任务
在Worker协程中调用$server->task($data),将耗时计算逻辑移入onTask回调,主协程立即返回,不阻塞调度。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
方法二:手动创建独立Task Worker进程
配置'task_worker_num' => 4,并在onTask中执行hash_hmac('sha256', $input, $key)或imagecreatefromjpeg()等重操作,避免污染Worker协程栈。
这一步操作起来很简单,直接把计算逻辑从go()里抽出来扔进onTask就行。
在协程内主动让出控制权
对无法拆分的长循环,插入Co::usleep(1)或Co::yield()。
例如遍历10万条数据做校验时,在每1000次迭代后执行一次Co::usleep(1),既保持计算连续性,又给调度器插入检查点。
【不要用原生sleep()或usleep(),它们会阻塞整个Worker进程】,必须使用协程版函数。
若循环体本身极轻(如单纯累加),可改用declare(ticks=1000)配合tick handler检测执行时间,但此方式需全局生效且有性能损耗,仅作兜底方案。










