目录
什么是 Lua 协同程序
Lua 协同程序 (Coroutine) 是一种轻量级的线程机制,允许函数在执行中暂停并稍后恢复。协同程序通过 coroutine
库实现,提供了一种非抢占式的多任务处理方式,与操作系统线程不同,它由程序显式控制切换。
为什么要使用协同程序
- 任务调度:手动控制执行顺序,避免阻塞。
- 异步模拟:实现类似协程的异步操作。
- 状态保存:暂停时保留局部变量状态。
- 轻量高效:比线程更低的资源开销。
Lua 协同程序的定义与特性
- 定义:通过
coroutine.create()
创建,返回一个线程对象(类型为thread
)。 - 特性:
- 可暂停 (
yield
) 和恢复 (resume
)。 - 每个协同程序有独立栈。
- 非抢占式,需显式切换。
- 状态:running、suspended、dead。
代码示例
基本协同程序
1 2 3 4 5 6 7 8 9 10 | -- 创建协同程序 local co = coroutine.create(function() print("开始") coroutine.yield("暂停") print("恢复") end) -- 运行协同程序 print(coroutine.resume(co)) -- 第一次运行 print(coroutine.resume(co)) -- 恢复运行 |
运行结果:
1 2 | true 开始 true 暂停 恢复 |
生产者-消费者模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -- 生产者 local producer = coroutine.create(function() for i = 1, 3 do print("生产: " .. i) coroutine.yield(i) end end) -- 消费者 local function consumer() while true do local status, value = coroutine.resume(producer) if not status or value == nil then break end print("消费: " .. value) end end consumer() |
运行结果:
1 2 3 4 5 6 | 生产: 1 消费: 1 生产: 2 消费: 2 生产: 3 消费: 3 |
协同程序状态
1 2 3 4 5 6 7 8 9 10 | local co = coroutine.create(function() print("运行中") coroutine.yield() end) print("状态: " .. coroutine.status(co)) -- suspended coroutine.resume(co) -- 运行 print("状态: " .. coroutine.status(co)) -- suspended coroutine.resume(co) -- 恢复并结束 print("状态: " .. coroutine.status(co)) -- dead |
运行结果:
1 2 3 4 | 状态: suspended 运行中 状态: suspended 状态: dead |
协同程序常用函数
函数 | 描述 | 示例 |
---|---|---|
coroutine.create(f) | 创建协同程序,返回 thread | co = coroutine.create(func) |
coroutine.resume(co, ...) | 启动或恢复协同程序 | coroutine.resume(co, arg) |
coroutine.yield(...) | 暂停并返回值 | coroutine.yield(1) |
coroutine.status(co) | 返回状态(running, suspended, dead) | coroutine.status(co) → “suspended” |
coroutine.running() | 返回当前运行的协同程序 | coroutine.running() → thread |
工作原理详解
- 栈管理:每个协同程序有独立栈,保存局部变量和调用状态。
- 切换:
yield
暂停并返回控制权,resume
恢复执行。 - 非抢占:切换由程序控制,无需操作系统调度。
优点与应用场景
优点
- 轻量:比线程占用更少内存。
- 可控:显式切换,逻辑清晰。
- 灵活:支持复杂流程设计。
应用场景
- 游戏开发:分步执行动画或 AI 逻辑。
- 任务调度:模拟多任务处理。
- 生成器:按需生成数据序列。
常见问题与注意事项
- 错误处理:
resume
返回状态和错误,需检查:
1 2 | local status, err = coroutine.resume(co) if not status then print("错误: " .. err) end |
- 死协同程序:
- 已结束的协同程序不能再次
resume
,状态为dead
。
- 嵌套调用:
- 协同程序内可创建其他协同程序,但需谨慎管理。
- 性能:
- 大量协同程序可能增加内存开销。
参考资料与出站链接
- 官方文档:
- 学习资源:
- 工具支持:
- ZeroBrane Studio:调试协同程序。
如果您需要更复杂的协同程序示例(如异步模拟或多任务调度),请告诉我,我会进一步扩展!
发表回复