7Programming in Lua(第4版)

协程

协作式多任务

coroutineyieldresume生产者-消费者

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第7章:协程

一、导读

1.1 本章学习目标

第7章讲解 Lua 的协程(coroutine):协作式多任务的基础。

本章核心学习目标:

  • 理解协程的概念:可暂停和恢复的函数
  • 掌握 coroutine 的基本操作
  • 理解协程的应用场景

1.2 为什么本章如此重要

协程是 Lua 实现协作式并发的核心机制。它在游戏开发、迭代器、状态机中广泛应用。

1.3 核心问题引导

协程和线程有什么区别?

coroutine.yield 和 coroutine.resume 如何配合?

协程适合什么场景?


二、核心概念详解

2.1 协程基础

lua
-- 创建协程
local co = coroutine.create(function()
    print("step 1")
    coroutine.yield()
    print("step 2")
    coroutine.yield()
    print("step 3")
end)

print(coroutine.status(co))  -- suspended

-- 恢复协程
coroutine.resume(co)  -- step 1
print(coroutine.status(co))  -- suspended

coroutine.resume(co)  -- step 2
coroutine.resume(co)  -- step 3
print(coroutine.status(co))  -- dead

2.2 yield 传值

lua
-- yield 可以返回值,resume 可以传值
local co = coroutine.create(function(x, y)
    print("first:", x, y)
    local a, b = coroutine.yield("result1")
    print("second:", a, b)
    return "done"
end)

print(coroutine.resume(co, 1, 2))   -- true  result1
print(coroutine.resume(co, 3, 4))   -- true  done
print(coroutine.resume(co))         -- false  cannot resume dead coroutine

2.3 协程作为迭代器

lua
-- 用协程实现迭代器
function permgen(a, n)
    n = n or #a
    if n <= 1 then
        coroutine.yield(a)
    else
        for i = 1, n do
            a[n], a[i] = a[i], a[n]
            permgen(a, n - 1)
            a[n], a[i] = a[i], a[n]
        end
    end
end

function permutations(a)
    local co = coroutine.create(function() permgen(a) end)
    return function()
        local _, res = coroutine.resume(co)
        return res
    end
end

for p in permutations({"a", "b", "c"}) do
    print(table.concat(p, ","))
end

三、实战案例

3.1 案例一:生产者-消费者模式

lua
function producer(consumer)
    local co = coroutine.create(function()
        for i = 1, 10 do
            local value = coroutine.yield(i)
            print("Producer received:", value)
        end
    end)
    
    while true do
        local ok, value = coroutine.resume(co)
        if not ok then break end
        consumer(value)
    end
end

function consumer(value)
    print("Consumer got:", value * 2)
end

producer(consumer)

四、本章小结

协程是可暂停和恢复的函数

yield 暂停并返回值,resume 恢复并传值

协程适合协作式多任务,不适合抢占式并发


五、思考与练习

协程和回调相比有什么优势?

如何实现一个协程池?


7/8协程
0%