PHP 8.2.13中Fiber代码执行异常,请求排查修复
问题排查与修复
问题根源
- 调度流程中断:
fiber1执行到Fiber::suspend()后回到主线程,但主线程没有后续逻辑触发fiber2执行,程序直接结束。 - fiber2未启动:
fiber2仅完成实例化,从未调用start()启动执行流程。 - 调度逻辑耦合错误:两个Fiber之间直接调用
resume的逻辑存在闭环缺失,且循环变量被错误覆盖,破坏了步进规则。
修复后的代码
<?php // 创建打印偶数的Fiber $fiber1 = new Fiber(function () use (&$fiber2) { for ($i = 0; $i < 10; $i += 2) { echo "Fiber 1: $i\n"; // 挂起时传递下一个奇数给调度逻辑 Fiber::suspend($i + 1); } }); // 创建打印奇数的Fiber $fiber2 = new Fiber(function () use (&$fiber1) { for ($i = 1; $i < 10; $i += 2) { echo "Fiber 2: $i\n"; // 挂起时传递下一个偶数给调度逻辑 Fiber::suspend($i + 1); } }); // 主线程负责调度两个Fiber,形成执行闭环 $currentFiber = $fiber1; $nextValue = null; while (!$currentFiber->isTerminated()) { if ($currentFiber->isStarted()) { $nextValue = $currentFiber->resume($nextValue); } else { $nextValue = $currentFiber->start(); } // 切换到另一个Fiber继续执行 $currentFiber = $currentFiber === $fiber1 ? $fiber2 : $fiber1; }
修复说明
- 主线程统一调度:新增循环逻辑,由主线程负责在两个Fiber间切换,确保一个Fiber挂起后,另一个能继续执行,直到所有任务完成。
- 简化Fiber职责:每个Fiber只负责打印对应数字,挂起时传递下一个需要处理的值,避免Fiber间直接调用
resume的耦合问题。 - 修正循环变量:移除对循环变量的错误赋值,保证循环步进逻辑正常运行。
运行修复后的代码,将得到预期输出:
Fiber 1: 0
Fiber 2: 1
Fiber 1: 2
Fiber 2: 3
Fiber 1: 4
Fiber 2: 5
Fiber 1: 6
Fiber 2: 7
Fiber 1: 8
Fiber 2: 9
内容的提问来源于stack exchange,提问作者Navid Vakili
相关产品推荐
相关产品推荐

