[牛人杂谈] Lua的协程

[复制链接]
 楼主| gejigeji521 发表于 2025-6-11 10:57 | 显示全部楼层 |阅读模式
Lua 的协程(coroutine)是一种轻量级的用户态线程,它允许在单个线程中实现协作式多任务处理。与操作系统线程不同,协程由程序员显式控制切换时机,不涉及内核上下文切换,因此更加高效。

Lua 协程的关键特点:
非抢占式:协程主动让出(yield)执行权,而不是被强制中断
协作式多任务:协程之间需要互相协作,不会自动切换
轻量级:创建和切换开销远小于操作系统线程
单线程执行:同一时间只有一个协程在执行



Lua 提供以下协程相关函数:

coroutine.create(f) - 创建一个新协程,参数f是协程函数
coroutine.resume(co[, val1, ...]) - 启动或恢复协程执行
coroutine.yield(...) - 挂起当前协程的执行
coroutine.status(co) - 查看协程状态
coroutine.wrap(f) - 创建协程并返回一个函数,调用该函数即恢复协程


Lua 协程有以下几种状态:

suspended:刚创建或已挂起
running:正在执行
normal:活动但不在运行(在恢复其他协程)
dead:函数执行完毕或出错终止


基本用法示例

  1. -- 创建一个协程
  2. local co = coroutine.create(function()
  3.     print("协程开始")
  4.     coroutine.yield("第一次暂停")
  5.     print("协程恢复")
  6.     return "结束"
  7. end)

  8. -- 第一次恢复协程
  9. local success, result = coroutine.resume(co)
  10. print(result)  -- 输出: 第一次暂停

  11. -- 第二次恢复协程
  12. success, result = coroutine.resume(co)
  13. print(result)  -- 输出: 结束

  14. print(coroutine.status(co))  -- 输出: dead


 楼主| gejigeji521 发表于 2025-6-11 10:57 | 显示全部楼层
更实用的生产者-消费者模式示例
  1. -- 生产者
  2. function producer()
  3.     local i = 0
  4.     return function()
  5.         while true do
  6.             i = i + 1
  7.             coroutine.yield(i)  -- 生产一个值并挂起
  8.         end
  9.     end
  10. end

  11. -- 消费者
  12. function consumer(prod)
  13.     for i = 1, 5 do
  14.         local status, value = coroutine.resume(prod)
  15.         print("消费:", value)
  16.     end
  17. end

  18. -- 创建生产者协程
  19. local prod = coroutine.create(producer())

  20. -- 消费者消费5个值
  21. consumer(prod)
 楼主| gejigeji521 发表于 2025-6-11 10:58 | 显示全部楼层
协程可以用来实现复杂的迭代器:
  1. function walk(dir)
  2.     return coroutine.wrap(function()
  3.         for name in io.popen("ls "..dir):lines() do
  4.             coroutine.yield(name)
  5.         end
  6.     end)
  7. end

  8. for filename in walk(".") do
  9.     print(filename)
  10. end

 楼主| gejigeji521 发表于 2025-6-11 10:58 | 显示全部楼层
注意事项
协程不是真正的并行,同一时间只有一个协程在执行

协程的挂起和恢复完全由程序员控制

协程适合I/O密集型任务,不适合CPU密集型任务

协程间的数据交换通过yield和resume的参数进行

Lua的协程提供了一种简单而强大的方式来实现协作式多任务,特别适合游戏开发、状态机实现和复杂的控制流场景。
迷雾隐者 发表于 2025-6-12 12:04 | 显示全部楼层
非常详细地解释了Lua协程的概念和特点,对于理解协程的工作原理非常有帮助。
脑洞星球居民 发表于 2025-6-12 13:00 | 显示全部楼层
协程的概念在Lua中实现得非常优雅,它提供了一种高效的方式来处理多任务,尤其是在需要频繁切换上下文的场景中。
穷得响叮当侠 发表于 2025-6-12 16:34 | 显示全部楼层
协程的概念在Lua中实现得非常巧妙,它提供了一种高效的方式来处理多任务,尤其是在I/O密集型的应用中。
chenqianqian 发表于 2025-6-13 08:05 来自手机 | 显示全部楼层
lua可以用来开发嵌入式了吗?
liangshuang95 发表于 2025-6-13 08:47 来自手机 | 显示全部楼层
非抢占式如何保证优先级任务执行的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

195

主题

2460

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部

195

主题

2460

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部