基本概念
Lua 的 Coroutine(协程)是一种轻量级的线程,它允许程序在单个线程中实现多个执行流的协作式调度。与操作系统线程不同,协程是完全由用户控制的,在用户态进行切换,不需要内核参与。
核心功能
创建协程
lua
co = coroutine.create(function()
print("协程开始执行")
end)
启动/恢复协程
lua
coroutine.resume(co) -- 输出:"协程开始执行"
挂起协程
lua
co = coroutine.create(function()
print("第一步")
coroutine.yield()
print("第二步")
end)
coroutine.resume(co) -- 输出:"第一步"
coroutine.resume(co) -- 输出:"第二步"
状态管理
协程有以下几种状态:
suspended(挂起):刚创建或调用coroutine.yield后的状态running(运行):正在执行的状态dead(结束):函数执行完毕的状态
可以通过 coroutine.status(co) 查询协程状态。
数据交换
协程支持在 coroutine.resume 和 coroutine.yield 之间传递数据:
lua
co = coroutine.create(function(x)
print("收到:"..x)
local y = coroutine.yield("返回1")
print("收到:"..y)
return "返回2"
end)
print(coroutine.resume(co, "输入1")) -- 输出:"收到:输入1" 和 "true 返回1"
print(coroutine.resume(co, "输入2")) -- 输出:"收到:输入2" 和 "true 返回2"
应用场景
- 迭代器实现:可以用协程实现复杂的迭代逻辑
- 状态机:将状态转换逻辑封装在协程中
- 协作式多任务:在单线程中模拟多任务处理
- 游戏开发:处理角色AI、动画序列等
- 网络编程:实现非阻塞IO的协程调度
示例:生产者-消费者模式
lua
function producer()
return coroutine.create(function()
while true do
local x = io.read()
coroutine.yield(x)
end
end)
end
function consumer(prod)
while true do
local status, value = coroutine.resume(prod)
if not status then break end
print("消费:"..value)
end
end
consumer(producer())
注意事项
- 协程不是抢占式的,需要显式调用
coroutine.yield让出执行权 - 协程的栈空间有限,深度递归可能导致栈溢出
- 协程间的数据共享需要注意同步问题
- 错误处理需要通过
coroutine.resume的返回值判断
扩展阅读
Lua 5.3+ 版本对协程做了优化,性能更好。在 LuaJIT 中协程的执行效率更高,适合高性能场景。