php 8.1.18 的 fiber 是基于 c 实现的用户态栈切换机制,核心为 zend_fiber、zend_fiber_context(封装寄存器保存/恢复)和 zend_fiber_scheduler(管理调度),通过 setjmp/longjmp 或汇编完成上下文切换,不依赖系统线程或事件循环,仅提供协作式控制流转移。

直接看 PHP 8.1.18 的纤程(Fiber)源码,核心在 Zend/zend_fiber.c 和 Zend/zend_fiber.h 这两个文件。它不是基于线程或系统调度器,而是用 C 实现的一套用户态栈切换机制,关键在于“保存当前执行上下文 + 切换到另一套上下文”。
关注三个核心数据结构
Fiber 的行为由底层结构体驱动:
- zend_fiber:每个 Fiber 实例的主结构,含状态(RUNNING/SUSPENDED/DEAD)、栈指针、寄存器快照、指向调度器的引用
-
zend_fiber_context:平台相关(x86_64 / aarch64),封装了 CPU 寄存器(如 rbp, rsp, rip)的保存与恢复逻辑,实际调用
setjmp/longjmp或汇编指令完成跳转 -
zend_fiber_scheduler:全局单例,管理当前活跃 Fiber、挂起队列和恢复调度逻辑;PHP 默认不提供调度器实现,
Fiber::suspend()只是交还控制权给上层调用者
从 start() 到 suspend() 的执行链路
当你写 $fiber->start(),源码中发生的是:
PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 分配独立栈空间(默认 256KB,可配置)
- 初始化
zend_fiber_context,把闭包函数地址设为入口点 - 调用
zend_fiber_swap_context(),将当前主线程上下文保存,再跳入新栈执行闭包 - 遇到
Fiber::suspend($value)时,立刻保存当前 Fiber 的寄存器状态,把$value存入返回值槽,并跳回上一次的上下文(通常是调用start()或resume()的地方)
resume() 不是唤醒,而是“继续跳转”
很多人误以为 resume() 是异步唤醒,其实它只是再次触发上下文切换:
- 检查目标 Fiber 状态是否为 SUSPENDED
- 把传入参数写入其寄存器槽(如 rdi/x0)
- 调用
zend_fiber_swap_context(),从当前上下文切回该 Fiber 的栈和寄存器 - Fiber 从
suspend()下一行继续执行,suspend()返回刚传入的值
不依赖操作系统,但也不自动并发
Fiber 本身不带事件循环或 I/O 多路复用。它的 suspend/resume 是同步协作式控制流转移——就像函数调用,只是调用方和被调用方共用一个线程。真正实现“并发 I/O”,需要你手动配合:
比如在 suspend() 前发起 cURL 异步请求,等收到通知后再 resume();或者用 ReactPHP 把 Fiber 封装进 Promise 链。源码里找不到 epoll 或 kqueue 的痕迹,它只做一件事:安全、轻量地切换栈。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










