相关文章推荐
爱逃课的毛豆  ·  如何用C语言实现读取一个字符串的后几位?_百度知道·  1 年前    · 
任性的菠菜  ·  C++判断文件是否存在_对象存储 ...·  1 年前    · 
谦和的冰棍  ·  Java反射的理解(六)-- ...·  1 年前    · 
力能扛鼎的键盘  ·  The controller ...·  1 年前    · 
满身肌肉的小刀  ·  PIE-scope, integrated ...·  1 年前    · 
Code  ›  【Lua】协程开发者社区
协程 lua yield
https://cloud.tencent.com/developer/article/2199899
深情的钱包
1 年前
六月丶

【Lua】协程

腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
六月丶
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > 【Lua】协程

【Lua】协程

作者头像
六月丶
发布 于 2022-12-26 18:09:50
521 0
发布 于 2022-12-26 18:09:50
举报
文章被收录于专栏: 六月-游戏开发 六月-游戏开发

什么是协程?

从多线程的角度看,协程(Coroutine)与线程(thread)类似:协程是一系列的可执行语句,拥有自己的栈、局部变量和指令指针,同时协程又与其它协程共享全局变量和其它几乎一切资源。 线程和协程的主要区别: 一个多线程程序可以同时并行运行多条线程,而协程却需要彼此协作地运行,即在任意时刻只能有一个协程运行,且协程的切换是在用户态手动控制的,只有当正在运行的协程显示的要求被挂起(suspend)时,其执行才会暂停。

Lua中的协程支持

提供库函数

Lua中的所有协程相关函数都放在coroutine表中。

注:中括号为可选参数

函数原型

作用

补充

coroutine.create(函数对象) -> 协程对象

创建一个协程对象并返回

type(协程对象) = thread

coroutine.resume(协程对象, [传递给协程函数的参数1,2,3..]) -> state, value

开始/继续执行一个协程

正常执行:返回true和yield返回值 ; 发生一个未捕获错误:返回false和错误信息

coroutine.yield([返回值])

挂起当前正在运行的协程

coroutine.status(协程对象) -> status

返回协程状态

create和yield后为挂起(suspended);执行过程为运行(running);执行完毕为死亡(dead);在A协程中唤醒B协程,这时A协程就为正常(normal)状态。

coroutine.wrap(协程主体函数) -> function

创建一个以传入函数作为主体函数的新协程,并返回一个函数

返回的函数类似resume,不同的是调用不会返回state只返回value,如果出错会抛出异常。

使用样例

如果我们需要计算并打印一段斐波那契数列,假设每一步计算都需要一秒钟时间,传统写法可以是这样:

function Fibonacci(n)
    local tab = {}
    local a, b = 1, 1
    for i = 1, n do
        table.insert(tab, a)
        local t = a + b
        a = b
        b = t
        Sleep(1)
    return tab
local fib = Fibonacci(10)
for i, v in ipairs(fib) do
    io.write(v.." ")
end

运行结果 : 1 1 2 3 5 8 13 21 34 55

运行过程 : 会先等待10秒运算,然后瞬间打印所有结果。

而计算过程直接卡死10秒显然是不太好的,通过协程可以优化这个问题。

协程计算可以这样写:

local coro = nil
function Fibonacci(n)
    local a, b = 1, 1
    for i = 1, n do
        coroutine.yield(a)      --挂起当前协程,并返回结果
        local t = a + b
        a = b
        b = t
        Sleep(1)
coro = coroutine.create(Fibonacci)
function GetFibonacciNext()
    --开始/继续执行一个协程   正常执行:返回true和yield返回值   发生一个未捕获错误:返回false和错误信息
    local state, value = coroutine.resume(coro, 10)         
    return value
for i = 1, 10 do
    io.write(GetFibonacciNext().." ")
end

运行结果 : 1 1 2 3 5 8 13 21 34 55

运行过程 : 每计算出一个结果(间隔1秒)就会立刻返回并打印该值,直到打印完10个数列项。

这样的运行方式显然会更加友好,即需要用到该数据时再计算。

将协程用作迭代器

上述的遍历结果,还可以改成迭代器的用法:

-- 把协程用作迭代器
function GetFibonacciNext(n)
    local co = coroutine.create(Fibonacci)
    return function()
        local state, value = coroutine.resume(co, n)
        return value
for v in GetFibonacciNext(10) do
 
推荐文章
爱逃课的毛豆  ·  如何用C语言实现读取一个字符串的后几位?_百度知道
1 年前
任性的菠菜  ·  C++判断文件是否存在_对象存储 OSS-阿里云帮助中心
1 年前
谦和的冰棍  ·  Java反射的理解(六)-- 通过反射了解集合泛型的本质-腾讯云开发者社区-腾讯云
1 年前
力能扛鼎的键盘  ·  The controller AdminPsMboModule is missing or invalid. - General topics - PrestaShop Forums
1 年前
满身肌肉的小刀  ·  PIE-scope, integrated cryo-correlative light and FIB/SEM microscopy | eLife
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号