• 友链

  • 首页

  • 文章归档
h u a n b l o g
h u a n b l o g

欢

HI,Friend

04月
21
Lua

Lua协程

发表于 2022-04-21 • 字数统计 2491 • 被 1,781 人看爆

协程与线程

同
协程是一系列的可执行语句,拥有自己的栈、局部变量和指令指针,同时协程又与其他协程共享了全局变量和其他几乎一切资源。

异
一个多线程程序可以并行运行多个线程,而协程却需要彼此协作地运行,即在任意指定的时刻只能有一个协程运行,且只有当正在运行的协程显式地要求被挂起时其执行才会暂停。

协程基础

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

协程创建

函数create用于创建新协程,该函数只有一个参数,即协程要执行的代码的函(协程体)。

函数create返回一个"thread"类型的值,即新协程。通常,函数create的参数是一个匿名函数

co = coroutine.create(function() print( "hi" ) end)
print(type(co))                 --> thread

协程状态

一个协程有以下四种状态,即挂起(suspended)、运行(running)、正常(normal)和死亡(dead)。

我们可以通过函数coroutine.status来检查协程的状态:

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

协程启动

函数coroutine.resume用于启动或再次启动一个协程的执行,并将其状态由挂起改为运行:

coroutine.resume(co)        --> hi

在最后一行加上一个分号来阻止输出函数resume的返回值。在上例中,协程体只是简单地打印了"hi"后便终止了,然后协程就变成了死亡状态:

print(coroutine.status(co))         --> dead

函数yield

可以让一个运行中的协程挂起自己,然后在后续恢复运行

co = coroutine.create(function ()
    for i = 1, 10 do
        print("co", i)
        coroutine.yield()
    end
end)

其中,协程进行了一个循环,在循环中输出数字并在每次打印后挂起。当唤醒协程后,它就会开始执行直到遇到第一个yield:

coroutine.resume(co)      --> co 1

此时,查看协程状态,会发现协程处于挂起状态,因此可以再次恢复运行:

coroutine.status(co)      --> suspended

当我们唤醒协程时,函数yield才会最终返回,然后协程会继续执行直到遇到下一个yield或执行结束:

coroutine.resume(co)      -->co 2
coroutine.resume(co)      -->co 3
...
coroutine.resume(co)      -->co 10
coroutine.resume(co)      -->不输出任何数据

再次调用会输出错误信息

coroutine.status(co)      --> false  cannot resume dead coroutine

  当协程A唤醒协程B时,协程A既不是挂起状态(因为不能唤醒协程A),也不是运行状态(因为正在运行的协程是B)。所以,协程A此时的状态就被称为正常状态。

resume-yield机制

通过一对resume-yield来交换数据。第一个resume 函数(没有对应等待它的yield)会把所有的额外参数传递给协程的主函数:

co = coroutine. create(function (a, b, c)
        print("co", a, b, c + 2)
    end)
coroutine.resume(co,1,2,3)           -->co 1 2 5

在函数coroutine.resume的返回值中,第一个返回值为true时表示没有错误,之后的返回值对应函数yield的参数:

co = coroutine.create(function (a, b)
        coroutine.yield(a + b, a - b)
    end)
print(coroutine.resume( co,20,10))    --> true 30 10

函数coroutine.yield的返回值是对应的resume的参数:

co =coroutine.create(function (x)
        print("co1", x)
        print("co2", coroutine.yield())
    end)

coroutine.resume(co, "hi")          --> co1 hi
coroutine.resume(co,4, 5)           --> co2 4 5

当一个协程运行结束时,主函数所返回的值都将变成对应函数resume的返回值:

co = coroutine.create(function ()
        return 6,7
    end)

print(coroutine.resume(co))           --> true  6   7
分享到:
Lua反射
Lua垃圾收集
  • 文章目录
  • 站点概览
欢

网红 欢

你能抓到我么?

Email RSS
看爆 Top5
  • mac系统版本与Xcode版本有冲突 4,080次看爆
  • JAVA_HOME环境配置问题 3,730次看爆
  • AssetBundle使用 3,499次看爆
  • VSCode配置C++开发环境 3,257次看爆
  • Lua反射 3,133次看爆

Copyright © 2025 欢 粤ICP备2020105803号-1

由 Halo 强力驱动 · Theme by Sagiri · 站点地图