Lua协程

先看一段代码

coAA = coroutine.create(
    function ()
        print('at coAA -- 1')
        --这里启动协程coBB
        coroutine.resume(coBB)
        print('at coAA -- 2')
    end
)

coBB = coroutine.create(
    function ()
        print('at coBB -- 1')
        print('at coBB -- 2')
        --这里启动协程coCC
        coroutine.resume(coCC)
        print('at coBB -- 3')
    end
)

coCC = coroutine.create(
    function ()
        print('at coCC -- 1')
        --这里挂起协程coCC
        coroutine.yield()
        print('at coCC -- 2')
    end
)

--这里启动协程coA
coroutine.resume(coAA)

运行结果
at coAA -- 1
at coBB -- 1
at coBB -- 2
at coCC -- 1
at coBB -- 3
at coAA -- 2

因为coCC被挂起,所以,没有输出
at coCC -- 2
可以调用coroutine.resume(coCC),触发挂起的协程

上面代码中主要用到coroutine的API
coroutine.create (f) --创建一个协程
coroutine.resume (co [, val1, ···]) --触发一个协程
coroutine.yield (···) --挂起(阻塞)一个协程
具体解释如下

coroutine库详解

(1)coroutine.create (f)

传一个函数参数,用来创建协程。返回一个“thread”对象。

(2)coroutine.isyieldable ()

如果正在运行的协程可以让出,则返回真。值得注意的是,只有主协程(线程)和C函数中是无法让出的。

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

这是一个非常重要的函数。用来启动或再次启动一个协程,使其由挂起状态变成运行状态。
可以这么说,resume函数相当于在执行协程中的方法。参数Val1...是执行协程co时传递给协程的方法。
首次执行协程co时,参数Val1...会传递给协程co的函数;
再次执行协程co时,参数Val1...会作为给协程co中上一次yeild的返回值。
不知道这句话大家理解了没,这是协程的核心。如果没理解也不用急,继续往下看,稍后我会详细解释。
resume函数返回什么呢?有3种情况:
1)、如果协程co的函数执行完毕,协程正常终止,resume 返回 true和函数的返回值。
2)、如果协程co的函数执行过程中,协程让出了(调用了yeild()方法),那么resume返回true和协程中调用yeild传入的参数。
3)、如果协程co的函数执行过程中发生错误,resume返回false与错误消息。
可以看到resume无论如何都不会导致程序崩溃。它是在保护模式下执行的。

(4)coroutine.running ()

用来判断当前执行的协程是不是主线程,如果是,就返回true。

(5)coroutine.status (co)

返回一个字符串,表示协程的状态。有4种状态:
1)、running。如果在协程的函数中调用status,传入协程自身的句柄,那么执行到这里的时候才会返回running状态。
2)、suspended。如果协程还未结束,即自身调用了yeild或还没开始运行,那么就是suspended状态。
3)、normal。如果协程Aresume协程B时,协程A处于的状态为normal。在协程B的执行过程中,协程A就一直处于normal状态。因为它这时候既不是挂起状态、也不是运行状态。
4)、dead。如果一个协程发生错误结束,或正常终止。那么就处于dead状态。如果这时候对它调用resume,将返回false和错误消息。

(6)coroutine.wrap (f)

wrap()也是用来创建协程的。只不过这个协程的句柄是隐藏的。跟create()的区别在于:
1)、wrap()返回的是一个函数,每次调用这个函数相当于调用coroutine.resume()。
2)、调用这个函数相当于在执行resume()函数。
3)、调用这个函数时传入的参数,就相当于在调用resume时传入的除协程的句柄外的其他参数。
4)、调用这个函数时,跟resume不同的是,它并不是在保护模式下执行的,若执行崩溃会直接向外抛出。

(7)coroutine.yield (···)

使正在执行的函数挂起。
传递给yeild的参数会作为resume的额外返回值。
同时,如果对该协程不是第一次执行resume,resume函数传入的参数将会作为yield的返回值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我们首先介绍一下什么是协程、然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复...
    17269780ceda阅读 740评论 0 6
  • “协程(coroutine)”于我而言还是比较新的概念,Lua 也是刚接触不久。不过碰巧这段时间我又在看 ES6 ...
    NARUTO_86阅读 1,731评论 0 3
  • 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制。多任务机制大致可划分为两种: ...
    JunChow520阅读 2,918评论 0 4
  • 一、 coroutine.resume()函数 用来首次启动或再次启动一个协程,使其由挂起状态变成运行状态。也可以...
    北山学者阅读 1,116评论 0 1
  • Lua中协同程序:意义和Unity中一样Lua中协同程序的函数被放在coroutine的表中协同程序状态:挂起、执...
    周末的游戏之旅阅读 113评论 0 0