美文网首页
关于Lua中协程coroutine的理解

关于Lua中协程coroutine的理解

作者: 北山学者 | 来源:发表于2019-06-23 15:01 被阅读0次
coroutine-resume-yield

一、 coroutine.resume()函数

用来首次启动或再次启动一个协程,使其由挂起状态变成运行状态。也可以这么说,resume函数相当于在执行协程中的方法。参数Val1...是执行协程co时传递给协程的参数。
(1) 首次调用resume执行协程co时,参数Val1...会赋值给协程co的函数,作为函数参数

(2) 以后再调用resume执行协程co时,参数Val1...会赋值给协程co中上一次yield的返回值

resume函数的返回有3种情况:

(1) 如果协程co的函数执行完毕,协程正常终止,resume 返回 true和函数的返回值。

(2) 如果协程co的函数执行过程中,协程让出了(调用了yield()方法),那么resume返回true和协程中调用yield传入的参数。

(3) 如果协程co的函数执行过程中发生错误,resume返回false与错误消息。

可以看到resume无论如何都不会导致程序崩溃。它是在保护模式下执行的

二、coroutine.yield()函数

使正在执行的协程挂起,注意是执行完该函数后才会使协程挂起

(1) yeild的参数会作为resume的第二个返回值

(2) 如果对该协程不是第一次执行resume,resume函数传入的参数将会作为yield的返回值

三、程序示例

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      -- 协程co的第7行,此时resume()传入的参数是赋值给了函数的
foo 2           -- 在第8行里面调用了函数foo(),执行到第2行的打印
main    true    4       -- 由于函数foo()的第3行yield()执行后挂起,参数是4,作为第15行的resume()的第二个返回值,最终打印了出来,到此,第15行执行完毕
co-body r           -- 第16行resume()再次唤醒协程co,接着上次yield()的地方继续执行,参数“r"被赋值给上次yield()的返回值,在第9行打印出来
main    true    11  -9  -- 在第10行yiled()后再次挂起协程co,并返回,此时参数a和b还是第一次resume()时的参数,1,10,所以yield()两个参数分别为11,-9,作为resum()的第二个返回值,最终被打印出来,到此,第16行执行完毕
co-body x   y       -- 第17行resume()再次唤醒协程co,传入的参数“x”,“y”被赋值给上次的yield()函数的返回值,即赋值给第10行的r,s,在第11行被打印出来
main    true    10  end -- 协程co在第12行返回,注意此时参数b仍然是第一次resume()时的参数2,值为10,至此协程co执行结束,变为dead状态,最终在第17行打印出来
main    false   cannot resume dead coroutine -- 第18行尝试再次resume()协程co,由于协程co已经为dead状态,所以直接返回并报错

四、Lua中协同的强大能力,在于通过resume-yield来交换数据:

(1)resume把参数传给程序(相当于函数的参数调用);

(2)数据由yield传递给resume;

(3)resume的参数传递给yield;

(4)协同代码结束时的返回值,也会传给resume

协同中的参数传递形势很灵活,一定要注意区分,在启动coroutine的时候,resume的参数是传给主程序的;在唤醒yield的时候,参数是传递给yield的。

co = coroutine.create(function (a, b) print("co", a, b, coroutine.yield()) end)
coroutine.resume(co, 1, 2)        --没输出结果,注意两个数字参数是传递给函数的
coroutine.resume(co, 3, 4, 5)        --co 1 2 3 4 5,这里的两个数字参数由resume传递给yield 

参考

1、Lua 协同程序(coroutine)
2、Lua中的协同程序 coroutine
3、深入理解lua的协程coroutine
4、Lua学习之coroutine总结
5、lua-Coroutine

相关文章

  • 关于Lua中协程coroutine的理解

    一、 coroutine.resume()函数 用来首次启动或再次启动一个协程,使其由挂起状态变成运行状态。也可以...

  • Python协程、yield、yield from

    前言 协程,又称微线程,纤程。英文名Coroutine。最近几年才在某些语言(如Lua)中得到广泛应用! 协程的特...

  • 协程

    lua将所有关于协同程序的函数放置在一个名为“coroutine”的table中。 例: 一个协程可以处于4种不同...

  • lua学习之协程

    lua中的另一个高级功能是coroutine(协程),协同式多线程的意思,不同于线程和进程,协程仅在显示的调用一个...

  • 理解协程coroutine

    对网上文章和文档的学习记录,非肥兔子原创。感谢原作者们 最近研究OpenResty的cosocket,了解到了协程...

  • [xlua]探索笔记之协程

    在c#里的协程一般是长这个样子的 xlua里也有对协程的支持。 这里的cs_coroutine 也是一个lua脚本...

  • 协程原理:函数调用过程、参数和寄存器

    SRS是单进程、单线程、多协程结构,协程(coroutine)背景以后再介绍,这篇文章介绍协程的重要基础,理解了这...

  • C#协程

    Unity中协程的执行原理 UnityGems.com给出了协程的定义: A coroutine is a fun...

  • JS 生成器 vs. Lua 协程

    “协程(coroutine)”于我而言还是比较新的概念,Lua 也是刚接触不久。不过碰巧这段时间我又在看 ES6 ...

  • python异步协程(aiohttp,asyncio)

    python异步协程 环境:python3.7.0 协程 协程,英文叫做 Coroutine,又称微线程,纤程,协...

网友评论

      本文标题:关于Lua中协程coroutine的理解

      本文链接:https://www.haomeiwen.com/subject/wcgiqctx.html