Lua 基础教学:第十二篇Lua 中的协程与并发编程 在本篇文章中,我们将深入探讨 Lua 中的协程(coroutines)和并发编程。协程是 Lua 提供的一种强大特性,允许我们在单线程环境中实现并发操作。 什么是协程?协程是一种控制结构,可以暂停和恢复函数的执行。与线程不同,协程是非抢占式的,即在一个协程运行时,不会自动切换到其他协程。我们需要显式地切换协程。 创建和使用协程Lua 提供了 coroutine 模块来创建和操作协程。主要的函数包括: coroutine.create: 创建一个新的协程 coroutine.resume: 恢复协程的执行 coroutine.yield: 暂停协程的执行 coroutine.status: 获取协程的状态 coroutine.wrap: 创建并返回一个函数,调用该函数时会自动恢复协程
创建协程我们可以使用 coroutine.create 函数创建一个协程。这个函数接受一个函数作为参数,并返回一个新的协程。 local co = coroutine.create(function()
for i = 1, 5 do
print("Co-routine: " .. i)
coroutine.yield() -- 暂停协程
end
end)恢复协程使用 coroutine.resume 可以恢复协程的执行。每次调用 resume,协程都会继续执行直到遇到 yield 或执行完毕。 coroutine.resume(co) -- 输出:Co-routine: 1
coroutine.resume(co) -- 输出:Co-routine: 2
coroutine.resume(co) -- 输出:Co-routine: 3
coroutine.resume(co) -- 输出:Co-routine: 4
coroutine.resume(co) -- 输出:Co-routine: 5获取协程状态使用 coroutine.status 可以获取协程的状态。可能的状态有: local status = coroutine.status(co)
print("Status: " .. status) -- 输出:Status: dead使用 coroutine.wrapcoroutine.wrap 创建一个协程并返回一个函数,每次调用该函数时会自动恢复协程。 local co = coroutine.wrap(function()
for i = 1, 3 do
print("Wrapped co-routine: " .. i)
coroutine.yield()
end
end)
co() -- 输出:Wrapped co-routine: 1
co() -- 输出:Wrapped co-routine: 2
co() -- 输出:Wrapped co-routine: 3协程之间的通信协程之间可以通过 yield 和 resume 传递参数。 local co = coroutine.create(function(a, b)
print("Sum: " .. (a + b))
local c, d = coroutine.yield(a + b)
print("Product: " .. (c * d))
end)
coroutine.resume(co, 10, 20) -- 输出:Sum: 30
coroutine.resume(co, 5, 2) -- 输出:Product: 10协程与生产者-消费者模式协程常用于实现生产者-消费者模式。 local producer = coroutine.create(function()
for i = 1, 5 do
print("Producing: " .. i)
coroutine.yield(i)
end
end)
local consumer = coroutine.create(function()
while true do
local status, value = coroutine.resume(producer)
if not status then break end
print("Consuming: " .. value)
end
end)
coroutine.resume(consumer)实现并发编程尽管 Lua 的协程是非抢占式的,但它们仍然可以用于实现并发编程。以下是一个简单的例子,展示如何使用协程实现并发任务调度: -- 定义任务
local function task(name, delay)
for i = 1, 5 do
print(name .. " - Step " .. i)
os.execute("sleep " .. delay) -- 模拟任务耗时
coroutine.yield()
end
end
-- 创建协程
local task1 = coroutine.create(function() task("Task 1", 1) end)
local task2 = coroutine.create(function() task("Task 2", 2) end)
-- 调度器
while coroutine.status(task1) ~= "dead" or coroutine.status(task2) ~= "dead" do
coroutine.resume(task1)
coroutine.resume(task2)
end在这个例子中,我们定义了两个任务 task1 和 task2,它们分别执行一些步骤并暂停。调度器循环恢复两个协程,模拟了并发执行。 总结在这篇教程中,我们深入探讨了 Lua 中的协程与并发编程。我们学习了如何创建和使用协程,如何在协程之间传递参数,以及如何利用协程实现生产者-消费者模式和并发任务调度。协程是 Lua 中非常强大和灵活的特性,适用于需要并发执行的场景。在接下来的教程中,我们将探讨 Lua 的错误处理和异常管理。 继续关注我们的 Lua 教程系列,如果你有任何问题或建议,请在评论区留言。 |