第 7 章 · 协程:自愿让出的执行权 章节摘要:协程是"可以暂停的函数"——不是线程,没有并行,只是一段执行状态在 yield 处冻结、在 resume 处苏醒。这个极简设计恰好命中嵌入场景的要害:宿主养不起抢占式调度的开销,就让脚本自己说"我先歇会"。本章两节:7.1 讲协程的概念、三状态生命周期与 create/resume/yield 三板斧;7.2 讲应用场景——生成器、生产者消费者、协作式调度与非阻塞驱动,看协程如何成为脚本世界的"时间片协议"。 学习目标 阅读完本章,你应当能够: 说清协程与线程的本质区别(协作让出对抢占调度、同线程对并行、无锁对共享内存),理解"自愿让出"对嵌入场景的意义;
章节摘要:协程是"可以暂停的函数"——不是线程,没有并行,只是一段执行状态在 yield 处冻结、在 resume 处苏醒。这个极简设计恰好命中嵌入场景的要害:宿主养不起抢占式调度的开销,就让脚本自己说"我先歇会"。本章两节:7.1 讲协程的概念、三状态生命周期与 create/resume/yield 三板斧;7.2 讲应用场景——生成器、生产者消费者、协作式调度与非阻塞驱动,看协程如何成为脚本世界的"时间片协议"。
阅读完本章,你应当能够:
协程是脚本对宿主的承诺:我会在合适的时机主动交还时间片,请放心把下一拍交给我。
从"一个会暂停的函数"出发,过四状态生命周期与五个动词,重点是 resume/yield 交叉处参数与返回值的走向——这扇"双向传送门"是协程全部语义的枢纽。状态查询与 wrap 快捷方式收尾。
生成器与迭代器(协程版替代闭包版)、生产者消费者管线(两段逻辑交替推进的缩影)、协作式调度器(游戏 AI 与协议状态机的组织骨架)、非阻塞模型(OpenResty 把同步写法嫁接到异步 IO 上的思路)。四个场景一个原理:让出点即切换点,切换权在脚本手里。
一句话论点:7.1 学"怎么让",7.2 学"何时让"——机制与时机,协程的全部。
7.1 机制:create · resume · yield · 状态流转 · 双向传送门 │ ▼ 何时 yield 7.2 时机:生成器产出处 · 管线交接处 · 调度节拍处 · IO 等待处 │ ├──→ 第 8 章 OpenResty:同步外观异步内核 └──→ 第 9 章 游戏脚本与状态机的协作调度
协程和闭包状态机的本质区别? 闭包把状态拆成 upvalue 手工搬运(程序员当搬运工),协程把整个执行现场(局部变量、指令位置、调用栈)自动封存——复杂度没有消失,只是从手动变成自动。状态机复杂到要画图维护时,就是该换协程的信号。
resume 与 yield 的参数值是怎么互流的? 记"双向传送门":resume 的参数流向协程(首跑当实参、续跑当 yield 的返回值),yield 与 return 的值流向调用方(接在 resume 返回的 true 后面)。错误走同一条门:协程内出错,resume 得 false 加错误值。
为什么说协程是"给宿主的承诺"? 让出点显式(yield 一处)、切换成本极低(无调度器无锁)、执行权始终在宿主手里——宿主零开销拿到"多段逻辑推进"的能力,脚本保住顺序代码的形态。这个契约是游戏 AI、网关 cosocket、事件循环共同的底层。
三句话带走本章:
**第一句:协程是会暂停的函数,不是线程。**无并行、无抢占、无锁;切换只发生在 yield 一处——省下的是宿主的调度器,换来的是脚本的顺序形态。
**第二句:传送门双向通行。**resume 的参数变成 yield 的返回值、yield 的值变成 resume 的返回值——参数、结果、错误、超时全走同一扇门,宿主驱动协议因此与 pcall 同构。
**第三句:让出点即切换点,也即风险点。**跨 yield 别持不可重入资源、别假设原子性、两步操作一口气做完——协作式的自由拿纪律来换。