• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Lua协程(coroutine)程序运行分析

    这是一段分析 lua 协程(协同程序,coroutine)的代码,来自 Lua reference manual interface (略有修改):

    复制代码 代码如下:

    function foo (a)
        print("foo", a)
        return coroutine.yield(2*a)
    end

    co = coroutine.create(function (a,b)
       print("co-body1", a, b)
       local r = foo(a+1)
       print("co-body2", r)
       local r, s = coroutine.yield(a+b, a-b)
       print("co-body3", r, s)
       return b, "end"
    end)

    print("1----")
    print("main", coroutine.resume(co, 1, 10))
    print("2----")
    print("main", coroutine.resume(co, "r"))
    print("3----")
    print("main", coroutine.resume(co, "x", "y"))
    print("4----")
    print("main", coroutine.resume(co, "x", "y"))


    运行效果如下:
    复制代码 代码如下:

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

    这里一共调用了 4 次 resume ,让我们来看看它是怎么运行的。

    第一次:

    复制代码 代码如下:

    print("main", coroutine.resume(co, 1, 10))

    1.执行 print("co-body1", a, b) ,a 和 b 的值为 resume 提供,a=1, b=10 ;
    2.计算 a+1=2 ,进入 foo(a) ,同时将刚才的计算结果通过 a 参数传递,执行 print("foo", a);
    3.考虑 return coroutine.yield(2*a) ;
    4.计算 2*a=4 ,碰到 yield,挂起 foo(a) 调用,将 4 返回给 resume 。注意,foo 的 return 还没有执行;
    5.resume 执行成功,返回 true, 4 。

    第二次:

    复制代码 代码如下:

    print("main", coroutine.resume(co, "r"))

    1.从上一次挂起的 foo(a) 调用开始执行,接着执行没有完成的 return 调用;
    2.因为 yield 返回 resume 的调用参数,此时 foo(a+1) 返回的值就是字符串 "r"。这里比较难理解。
    因为大家可能会顺理成章地认为 local r 这个变量的值应该是 yield(2*a) 中的 2*a 的值。
    需要注意的是, yield 的返回值 与 yield 参数的值 是不同的。
    前者你可以将其保存在一个变量中,或者 return 它,或者不使用它(不保存 yield 的返回结果);后者则是 resume 的返回值。
    3.执行 print("co-body2", r) ,r 的值为 "r" ;
    4.考虑 local r, s = coroutine.yield(a+b, a-b) ;
    5.计算 a+b=11, a-b=-9 ,碰到 yield ,挂起 co 的调用,将 11 和 9 返回给 resume 。注意,此时 local r, s 的赋值还没有开始。
    这里不太好理解的是,为什么 a 的值不是 "r" ?因为 "r" 已经被上面的 yield 的返回值给消费掉了。
    6.resume 执行成功,返回 true, 11, -9 。

    第三次:

    复制代码 代码如下:

    print("main", coroutine.resume(co, "x", "y"))

    1.从上一次 yield 的地方开始执行,接着执行没有完成的 local r, s = 赋值。上面提到, yield 会返回 resume 的调用参数,因此 r 和 s 的值就是 "x" 和 "y" ;
    2.执行 print("co-body3", r, s) 进行打印;
    3.考虑 return b, "end" ;
    4.b 的值一直都是 10 没有变,这里直接返回了,同时返回的还有 "end" 这个字符串;
    5.由于协程函数返回的时候,它的所有返回值都作为 resume 的返回值返回。因此这里的 resume 执行成功,返回 10, "end" 。

    第四次:

    复制代码 代码如下:

    print("main", coroutine.resume(co, "x", "y"))

    由于 co 函数已经返回,它处于 dead 状态,不能 resume ,因此第 4 次 resume 失败。

    您可能感兴趣的文章:
    • Lua的协程(coroutine)简介
    • Lua之协同程序coroutine代码实例
    • Lua协同程序(COROUTINE)运行步骤分解
    • Lua协同程序函数coroutine使用实例
    • Lua编程示例(七):协同程序基础逻辑
    • 举例详解Lua中的协同程序编程
    • Lua中的协同程序详解
    • Lua中的协同程序之resume-yield间的数据返回研究
    • Lua中的协同程序探究
    • Lua协同程序coroutine的简介及优缺点
    上一篇:浅谈Lua语句
    下一篇:Lua脚本实现递归删除一个文件夹
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Lua协程(coroutine)程序运行分析 Lua,协程,coroutine,程序,运行,