- Lua 教程
- Lua - 首页
- Lua 基础
- Lua - 概述
- Lua - 环境
- Lua - 基本语法
- Lua - 注释
- Lua - 打印 Hello World
- Lua - 变量
- Lua - 数据类型
- Lua - 运算符
- Lua - 循环
- Lua - 条件语句
- Lua - 函数
- Lua - 日期和时间
- Lua 数组
- Lua - 数组
- Lua - 多维数组
- Lua - 数组长度
- Lua - 迭代数组
- Lua 迭代器
- Lua - 迭代器
- Lua 列表
- Lua - 在列表中搜索
- Lua 模块
- Lua - 模块
- Lua - 命名空间
- Lua 元表
- Lua - 元表
- Lua 协程
- Lua协程
- Lua 文件处理
- Lua - 文件 I/O
- Lua 库
- Lua - 标准库
- Lua - 数学库
- Lua - 操作系统功能
- Lua 有用资源
- Lua - 快速指南
- Lua - 有用资源
- Lua - 讨论
Lua协程
简介
协程本质上是协作式的,它允许以受控的方式执行两种或多种方法。使用协程时,在任何给定时间,只有一个协程运行,并且此运行的协程仅在其显式请求暂停时才会暂停其执行。
上述定义可能看起来含糊不清。让我们假设我们有两个方法,一个是主程序方法,另一个是协程。当我们使用 resume 函数调用协程时,它开始执行;当我们调用 yield 函数时,它暂停执行。同一个协程可以使用另一个 resume 函数调用从暂停的地方继续执行。这个过程可以持续到协程执行结束。
协程中可用的函数
下表列出了 Lua 中所有可用的协程函数及其对应的用途。
序号 | 方法及用途 |
---|---|
1 |
使用函数 f 创建一个新的协程,并返回一个“线程”类型的对象。 |
2 |
恢复协程 co 并传递参数(如有)。它返回操作状态和可选的其他返回值。 |
3 |
返回正在运行的协程,如果在主线程中调用则返回 nil。 |
4 |
根据协程的状态返回运行中、正常、暂停或死亡等值之一。 |
5 |
与 |
6 |
暂停正在运行的协程。传递给此方法的参数作为 resume 函数的附加返回值。 |
示例
让我们来看一个例子来理解协程的概念。
main.lua
co = coroutine.create(function (value1,value2) local tempvar3 = 10 print("coroutine section 1", value1, value2, tempvar3) local tempvar1 = coroutine.yield(value1+1,value2+1) tempvar3 = tempvar3 + value1 print("coroutine section 2",tempvar1 ,tempvar2, tempvar3) local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2) tempvar3 = tempvar3 + value1 print("coroutine section 3",tempvar1,tempvar2, tempvar3) return value2, "end" end) print("main", coroutine.resume(co, 3, 2)) print("main", coroutine.resume(co, 12,14)) print("main", coroutine.resume(co, 5, 6)) print("main", coroutine.resume(co, 10, 20))
输出
运行上述程序时,将得到以下输出。
coroutine section 1 3 2 10 main true 4 3 coroutine section 2 12 nil 13 main true 5 1 coroutine section 3 5 6 16 main true 2 end main false cannot resume dead coroutine
上述示例的功能?
如前所述,我们使用 resume 函数启动操作,使用 yield 函数停止操作。此外,您可以看到协程的 resume 函数接收多个返回值。
首先,我们创建一个协程并将其赋值给变量名 co,协程接收两个变量作为参数。
当我们调用第一个 resume 函数时,值 3 和 2 保留在临时变量 value1 和 value2 中,直到协程结束。
为了让您理解这一点,我们使用了 tempvar3,它最初为 10,并且由于 value1 在协程执行过程中始终保持为 3,因此它通过后续的协程调用更新为 13 和 16。
第一个
coroutine.yield
将两个值 4 和 3 返回给 resume 函数,我们通过更新 yield 语句中的输入参数 3 和 2 来获得这些值。它还接收协程执行的真/假状态。关于协程的另一件事是如何处理 resume 调用的下一个参数,在上面的例子中;您可以看到变量
coroutine.yield
接收下一个调用的参数,这提供了一种强大的方法来使用现有参数值的关系执行新操作。最后,一旦协程中的所有语句都执行完毕,后续调用将返回 false 和“无法恢复已死亡的协程”语句作为响应。
另一个协程示例
让我们来看一个简单的协程,它使用 yield 函数和 resume 函数返回 1 到 5 的数字。如果协程不存在,则创建协程;否则恢复现有的协程。
main.lua
function getNumber() local function getNumberHelper() co = coroutine.create(function () coroutine.yield(1) coroutine.yield(2) coroutine.yield(3) coroutine.yield(4) coroutine.yield(5) end) return co end if(numberHelper) then status, number = coroutine.resume(numberHelper); if coroutine.status(numberHelper) == "dead" then numberHelper = getNumberHelper() status, number = coroutine.resume(numberHelper); end return number else numberHelper = getNumberHelper() status, number = coroutine.resume(numberHelper); return number end end for index = 1, 10 do print(index, getNumber()) end
输出
运行上述程序时,将得到以下输出。
1 1 2 2 3 3 4 4 5 5 6 1 7 2 8 3 9 4 10 5
协程经常与多编程语言的线程进行比较,但我们需要理解的是,协程具有与线程类似的功能,但它们一次只执行一个,永远不会并发执行。
我们控制程序执行顺序以满足需求,并临时保留某些信息。在协程中使用全局变量为协程提供了更大的灵活性。