Lua协同程序(coroutine)

Lua 协同程序基础概念

Lua 协同程序(coroutine)是一种用户态轻量级线程,允许在单个线程中实现协作式多任务。与操作系统线程不同,协同程序由开发者显式控制切换,不涉及系统调度开销。

  • 特点
    • 非抢占式:需手动调用 yieldresume 切换执行权。
    • 低开销:创建和切换成本远低于系统线程。
    • 共享状态:所有协同程序共享相同 Lua 状态,无需考虑竞态条件。

创建与启动协同程序

通过 coroutine.createcoroutine.wrap 创建,区别在于错误处理和返回值:

lua 复制代码
-- 方式1:create返回线程对象,需配合coroutine.resume启动
local co = coroutine.create(function()
    print("协同程序执行")
end)
coroutine.resume(co)

-- 方式2:wrap返回可直接调用的函数
local f = coroutine.wrap(function()
    print("协同程序执行")
end)
f()

控制执行流程

协同程序通过 yield 暂停执行,通过 resume 恢复执行:

lua 复制代码
local co = coroutine.create(function()
    for i = 1, 3 do
        print("Yield", i)
        coroutine.yield()
    end
end)

coroutine.resume(co) -- 输出 Yield 1
coroutine.resume(co) -- 输出 Yield 2
coroutine.resume(co) -- 输出 Yield 3

数据交换

yieldresume 可双向传递数据:

lua 复制代码
local co = coroutine.create(function(a)
    print("接收参数:", a)
    local b = coroutine.yield("第一次yield返回")
    print("恢复后接收:", b)
    return "结束"
end)

local _, msg1 = coroutine.resume(co, "初始参数") -- 输出:接收参数: 初始参数
print(msg1) -- 输出:第一次yield返回

local _, msg2 = coroutine.resume(co, "新参数")   -- 输出:恢复后接收: 新参数
print(msg2) -- 输出:结束

状态查询

通过 coroutine.status 检查协同程序状态:

  • running:当前正在运行的协程。
  • suspended:已暂停或未启动。
  • dead:执行完毕或出错终止。
lua 复制代码
print(coroutine.status(co)) -- 输出 dead

典型应用场景

  1. 生产者-消费者模型

    lua 复制代码
    local producer = coroutine.create(function()
        while true do
            local x = io.read()
            coroutine.yield(x)
        end
    end)
    
    local consumer = function()
        while true do
            local _, value = coroutine.resume(producer)
            print("消费:", value)
        end
    end
  2. 状态机

    将复杂状态逻辑拆解为多个 yield 阶段,简化代码结构。

  3. 协作式任务调度

    在单线程中模拟多任务并发,如游戏中的NPC行为控制。

注意事项

  • 避免无限循环未 yield,会导致程序阻塞。
  • resume 调用可能引发错误,需用 pcall 包裹处理。
  • 协同程序不适用于CPU密集型并行计算,适合I/O密集型任务。

附:完整生命周期示例

lua 复制代码
local co = coroutine.create(function()
    coroutine.yield("暂停")
    return "完成"
end)

print(coroutine.resume(co)) -- true, "暂停"
print(coroutine.resume(co)) -- true, "完成"
print(coroutine.status(co)) -- dead
相关推荐
慢慢沉10 小时前
Lua(数据库访问)
开发语言·数据库·lua
慢慢沉1 天前
Lua元表(Metatable)
lua
慢慢沉2 天前
Lua(字符串)
开发语言·lua
慢慢沉2 天前
Lua(数组)
开发语言·lua
慢慢沉2 天前
Lua(迭代器)
开发语言·lua
慢慢沉2 天前
Lua基本语法
开发语言·lua
Feng.Lee2 天前
接口测试Postman工具高级使用技巧
功能测试·测试工具·lua·postman·可用性测试
三翼鸟数字化技术团队3 天前
鸿蒙平台运行Lua脚本
lua·harmonyos