目录
什么是 Lua 协同程序
Lua 协同程序 (Coroutine) 是一种轻量级的线程机制,允许函数在执行中暂停并稍后恢复。协同程序通过 coroutine
库实现,提供了一种非抢占式的多任务处理方式,与操作系统线程不同,它由程序显式控制切换。
为什么要使用协同程序
- 任务调度:手动控制执行顺序,避免阻塞。
- 异步模拟:实现类似协程的异步操作。
- 状态保存:暂停时保留局部变量状态。
- 轻量高效:比线程更低的资源开销。
Lua 协同程序的定义与特性
- 定义:通过
coroutine.create()
创建,返回一个线程对象(类型为thread
)。 - 特性:
- 可暂停 (
yield
) 和恢复 (resume
)。 - 每个协同程序有独立栈。
- 非抢占式,需显式切换。
- 状态:running、suspended、dead。
代码示例
基本协同程序
-- 创建协同程序
local co = coroutine.create(function()
print("开始")
coroutine.yield("暂停")
print("恢复")
end)
-- 运行协同程序
print(coroutine.resume(co)) -- 第一次运行
print(coroutine.resume(co)) -- 恢复运行
运行结果:
true 开始
true 暂停 恢复
生产者-消费者模型
-- 生产者
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
消费: 1
生产: 2
消费: 2
生产: 3
消费: 3
协同程序状态
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
运行结果:
状态: 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
返回状态和错误,需检查:
local status, err = coroutine.resume(co)
if not status then print("错误: " .. err) end
- 死协同程序:
- 已结束的协同程序不能再次
resume
,状态为dead
。
- 嵌套调用:
- 协同程序内可创建其他协同程序,但需谨慎管理。
- 性能:
- 大量协同程序可能增加内存开销。
参考资料与出站链接
- 官方文档:
- 学习资源:
- 工具支持:
- ZeroBrane Studio:调试协同程序。
如果您需要更复杂的协同程序示例(如异步模拟或多任务调度),请告诉我,我会进一步扩展!
发表回复