Lua-Coroutine(协同例程)

Lua 支持 coroutine ,这个东西也被称为协同式多线程 (collaborative multithreading) 。
Lua 为每个 coroutine 提供一个独立的运行线路。
然而和多线程系统中的线程不同,coroutine 只在显式的调用了 yield 函数时才会挂起。

coroutine.create(func)

创建一个 coroutine 需要调用一次 coroutine.create() 。
它只接收单个参数,这个参数是 coroutine 的主函数。
create 函数仅仅创建一个新的 coroutine 然后返回它的控制器(一个类型为 thread 的对象);
它并不会启动 coroutine 的运行。

coroutine.resume(cor, param1, param2, ...)

当你第一次调用 coroutine.resume 时,
所需传入的第一个参数就是 coroutine.create 的返回值。
这时,coroutine 从主函数的第一行开始运行。
接下来传入 coroutine.resume 的参数将被传进 coroutine 的主函数。
在 coroutine 开始运行后,它讲运行到自身终止或是遇到一个 yields 。

coroutine 可以通过两种方式来终止运行:
一种是正常退出,指它的主函数返回(最后一条指令被运行后,无论有没有显式的返回指令);
另一种是非正常退出,它发生在未保护的错误发生的时候。
第一种情况中, coroutine.resume 返回 true ,
接下来会跟着 coroutine 主函数的一系列返回值。
第二种发生错误的情况下, coroutine.resume 返回 false ,
紧接着是一条错误信息。

coroutine 中切换出去,可以调用 coroutine.yield
当 coroutine 切出,与之配合的 coroutine.resume 就立即返回,
甚至在 yield 发生在内层的函数调用中也可以(就是说,
这不限于发生在主函数中,也可以是主函数直接或间接调用的某个函数里)。
在 yield 的情况下,coroutine.resume 也是返回 true
紧跟着那些被传入 coroutine.yield 的参数,传入yield接口的参数会作为resume()接口的返回值。
等到下次你在继续同样的 coroutine ,将从调用 yield 的断点处运行下去。
断点处 yield 的返回值将是下一次调用 coroutine.resume 传入的参数。

coroutine.wrap(func)

类似 coroutine.create ,
coroutine.wrap 这个函数也将创建一个 coroutine ,
但是它并不返回 coroutine 本身,而是返回一个函数取而代之。一旦你调用这个返回函数,就会切入 coroutine 运行。
所有传入这个函数的参数等同于传入 coroutine.resume 的参数。
coroutine.wrap 会返回所有应该由除第一个(错误代码的那个布尔量)
之外的由 coroutine.resume 返回的值。
和 coroutine.resume 不同,
coroutine.wrap 不捕获任何错误;
所有的错误都应该由调用者自己传递。

实例1:

function foo (a)
    print("foo", a)
    return coroutine.yield(a)
end
    
co = coroutine.create(function (x)
    print("co-body", x)
    local c1, c2 = foo(x)
    print("co-body", c1, c2)
    local c1, c2, c3 = coroutine.yield(c1, c2)
    print("co-body", c1, c2, c3)
    local c1, c2, c3, c4 = coroutine.yield(c1, c2, c3)
    print("co-body", c1, c2, c3, c4)
    return "end"
end)
    
print("main", coroutine.resume(co, 1))
print("main", coroutine.resume(co, 11, 22))
print("main", coroutine.resume(co, 111, 222, 333))
print("main", coroutine.resume(co, 1111, 2222, 3333, 4444))
print("main", coroutine.resume(co, 11111, 22222, 33333, 44444, 55555))

运行结果:

 

实例2:

function foo (a)
    print("foo", a)
    return coroutine.yield(a)
end
co = coroutine.wrap(function (x)
    print("co-body", x)
    local c1, c2 = foo(x)
    print("co-body", c1, c2)
    local c1, c2, c3 = coroutine.yield(c1, c2)
    print("co-body", c1, c2, c3)
    local c1, c2, c3, c4 = coroutine.yield(c1, c2, c3)
    print("co-body", c1, c2, c3, c4)
    return "end"
end)
    
print("main", co(1))
print("main", co(11, 22))
print("main", co(111, 222, 333))
print("main", co(1111, 2222, 3333, 4444))
print("main", co(11111, 22222, 33333, 44444, 55555))

运行结果: 

 

 

转载自:https://www.wenjiangs.com/doc/2-11-coroutine-%ef%bc%88%e5%8d%8f%e5%90%8c%e4%be%8b%e7%a8%8b%ef%bc%89

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值