Lua的协程(coroutine)

--------------------------------------------------------------------------------
-- 不携带参数
--------------------------------------------------------------------------------
local main = function()
    print("step1")
    coroutine.yield()
    print("step2")
end
local co = coroutine.create(main)
coroutine.resume(co)
coroutine.resume(co)
-- 输出
step1 step2

以上是最简单的协程演示了html

讲解:多线程

1.coroutine.create建立一个协程函数

2.第一次coroutine.create运行到main函数的coroutine.yield()函数处中止this

3.再次运行coroutine.create而后继续在main函数中断处运行,即运行main函数的第二个printlua

 

协程的参数稍微麻烦一些,最好能讲下面的详解看完,就能明白了,这里先上个最简单的演示参数传递的例子spa

--------------------------------------------------------------------------------
-- 携带参数传递
--------------------------------------------------------------------------------
local main = function(arg1)
    print (arg1)
    print (coroutine.yield("yield"))
    print (arg1)
end
local co = coroutine.create(main)
print(coroutine.resume(co, "resume1"))
print(coroutine.resume(co, "resume2"))  
-- ouput:
resume1
true    yield
resume2
resume1
true

对于协程的详解


 

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

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

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

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

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

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

 

    Lua语言实现的协程是一种非对称式(asymmetric)协程,或称半对称式(semi-symmetric)协程,又或干脆就叫半协程(semi-coroutine)。

    这种协程机制之因此被称为非对称的,是由于它提供了两种传递程序控制权的操做:

  • 一种是(重)调用协程(经过coroutine.resume);
  • 另外一种是挂起协程并将程序控制权返回给协程的调用者(coroutine.yield)。

    一个非对称协程能够看作是从属于它的调用者的,两者的关系很是相似于例程(routine)与其调用者之间的关系。既然有非对称式协程,固然也就有对称式(symmetric)协程了,它的特色是只有一种传递程序控制权的操做,即将控制权直接传递给指定的协程。曾经有这么一种说法,对称式和非对称式协程机制的能力并不等价,但事实上很容易根据前者来实现后者。

 

coroutine.create (f)

Creates a new coroutine, with body ff must be a Lua function. Returns this new coroutine, an object with type "thread".


 

coroutine.resume (co [, val1, ···])

Starts or continues the execution of coroutine co. The first time you resume a coroutine, it starts running its body. The values val1, ··· are passed as the arguments to the body function. If the coroutine has yielded, resume restarts it; the values val1, ··· are passed as the results from the yield.

If the coroutine runs without any errors, resume returns true plus any values passed to yield (if the coroutine yields) or any values returned by the body function (if the coroutine terminates). If there is any error, resume returns false plus the error message.


 

coroutine.running ()

Returns the running coroutine, or nil when called by the main thread.


 

coroutine.status (co)

Returns the status of coroutine co, as a string: "running", if the coroutine is running (that is, it called status); "suspended", if the coroutine is suspended in a call to yield, or if it has not started running yet; "normal" if the coroutine is active but not running (that is, it has resumed another coroutine); and "dead" if the coroutine has finished its body function, or if it has stopped with an error.


 

coroutine.yield (···)

Suspends the execution of the calling coroutine. The coroutine cannot be running a C function, a metamethod, or an iterator. Any arguments to yield are passed as extra results to resume.


 

coroutine.wrap (f)

Creates a new coroutine, with body ff must be a Lua function. Returns a function that resumes the coroutine each time it is called. Any arguments passed to the function behave as the extra arguments to resume. Returns the same values returned by resume, except the first boolean. In case of error, propagates the error.

相关文章
相关标签/搜索