返回介绍

2.11 - Coroutine (协同例程)

发布于 2019-08-25 13:16:32 字数 2288 浏览 1170 评论 0 收藏 0

Lua 支持 coroutine ,这个东西也被称为协同式多线程 (collaborative multithreading) 。

Lua 为每个 coroutine 提供一个独立的运行线路。

然而和多线程系统中的线程不同,coroutine 只在显式的调用了 yield 函数时才会挂起。

创建一个 coroutine 需要调用一次 coroutine.create

它只接收单个参数,这个参数是 coroutine 的主函数。

create 函数仅仅创建一个新的 coroutine 然后返回它的控制器(一个类型为 thread 的对象),它并不会启动 coroutine 的运行。

当你第一次调用 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 的参数。

等到下次你在继续同样的 coroutine ,将从调用 yield 的断点处运行下去。

断点处 yield 的返回值将是 coroutine.resume 传入的参数。

类似 coroutine.createcoroutine.wrap 这个函数也将创建一个 coroutine ,但是它并不返回 coroutine 本身,而是返回一个函数取而代之。一旦你调用这个返回函数,就会切入 coroutine 运行。

所有传入这个函数的参数等同于传入 coroutine.resume 的参数。

coroutine.wrap 会返回所有应该由除第一个(错误代码的那个布尔量)之外的由 coroutine.resume 返回的值。

coroutine.resume 不同,coroutine.wrap 不捕获任何错误;

所有的错误都应该由调用者自己传递。

看下面这段代码展示的一个例子:

 function foo (a)
 print("foo", a)
 return coroutine.yield(2*a)
 end
 
 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("main", coroutine.resume(co, 1, 10))
 print("main", coroutine.resume(co, "r"))
 print("main", coroutine.resume(co, "x", "y"))
 print("main", coroutine.resume(co, "x", "y"))

当你运行它,将得到如下输出结果:

 co-body 1 10
 foo 2
 
 main true 4
 co-body r
 main true 11 -9
 co-body x y
 main true 10 end
 main false cannot resume dead coroutine

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文