Lua-协程coroutine

2023-04-28T16:42:00

coroutine.create(fn)

创建协程,传入参数为function,返回新创建的协程,对应Lua类型thread

coroutine.resume(co,...)

开始或者继续执行协程,第一个参数是已创建的协程,后续是可变参数
如果是第一次调用,传入的参数传给协程对应的函数
否则,传入的参数传给上次协程中断的地方,通过coroutine.yield获取

函数返回第一个参数是boolean,表示协程执行结果是否有错误
如果没有错误,返回true,后续参数返回coroutine.yield对应的参数或者函数的返回值
否则,返回false,第二个参数是错误信息error message

coroutine.yield(...)

用于挂起当前执行的协程

参数为可变参数列表,调用coroutine.resume继续执行协程时,会把可变参数返回给coroutine.resume

返回值是coroutine.resume传入进来的参数

coroutine.wrap(fn)

也是创建协程,参数为function,返回的是函数,协程句柄是隐藏的。

  • 每次调用这个函数,相当于调用了coroutine.resume
  • 调用函数传入的参数,也相当于coroutine.resume传入参数
  • coroutine.resume调用是在保护模式下执行的,执行报错会返回false和错误信息,但是coroutine.wrap会直接抛出错误信息

coroutine.status(co)

获取协程的状态,返回值是string,有以下几种状态

  • running 正在运行中,在协程的函数中,传入协程自身的句柄,执行到这里的时候才会返回running状态
  • suspended 挂起状态,协程刚创建或者执行coroutine.yield
  • normal 协程A中调用 resume 协程B,在B执行过程中,A就处于normal状态
  • dead 结束状态,协程发生错误或者正常允许结束,返回dead状态,这时候再调用resume将会报错

coroutine.isyieldable()

如果正在允许的协程可以让出,则返回true。只有主协程(线程)和C函数是无法让出的

实例分析

local function foo(a)
    print("foo", a)
    return coroutine.yield(2 * a)
end

local co = coroutine.create(function ( a, b )
    print("co-body", a, b)
    local r = foo(a + 1)
    print("co-body", r)
    local r, s = coroutine.yield(a + b, a - b)
    print("co-body", r, s)
    return b, "end"
end)

print(coroutine.resume(co, 1, 10))
--  结果
--  co-body  1   10  首次执行协程,传入函数,执行打印
--  foo 2    调用foo,传入 a+1,也就是2,执行打印
--  true 4   执行yield,传参数为 2*a 也就是 4,返回给 coroutine.resume


print(coroutine.resume(co, "r"))
--  结果
--  co-body r yield返回的是resume传入的r
--  true  11  -9 resume获得的结果是yield返回的a+b和a-b,也就是 11 和 -9

print(coroutine.resume(co, "x", "y"))
--  结果
--  co-body x y     yield返回的是resume传入的x,y
--  true  10 end    协程最后的return返回值是b,也就是10,end字符串

print(coroutine.resume(co, "x", "y"))
--  结果
--  false cannot resume dead coroutine  上一步执行resume之后,协程已是dead状态,再执行resume会报错
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »