【Programming in Lua】协同程序

看了好几次协同程序都始终没能搞懂其中resume是如何与yield进行数据交流的,今天终于看懂了,让我们从头说起

基本语法

coroutine.create( )

创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用

coroutine.resume( )

重启coroutine,和create配合使用

coroutine.yield()

挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果

coroutine.status( )

查看coroutine的状态

注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序

coroutine.wrap()

创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复

coroutine.running()

返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号

实例讲解

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end
 
co = coroutine.create(function (a , b)
    print("第一次协同程序执行输出", a, b) -- co-body 1 10
    local r = foo(a + 1)
     
    print("第二次协同程序执行输出", r)
    local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入
     
    print("第三次协同程序执行输出", r, s)
    return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
end)
       
print("main", coroutine.resume(co, 1, 10)) -- true, 4
print("--分割线----")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
print("---分割线---")

上面代码的输出如下

第一次协同程序执行输出    1    10
foo 函数输出    2
main    true    4
--分割线----
第二次协同程序执行输出    r
main    true    11    -9
---分割线---
第三次协同程序执行输出    x    y
main    true    10    结束协同程序
---分割线---
main    false    cannot resume dead coroutine
---分割线---

个人分析

第一个分割线之前的内容很好理解,resume调用时,参数传递分两种情况,一种是第一次,把参数传递给协程主程序,之后的resume就把参数传递给yield函数,继续协程函数运行。

首先第一次传递参数给主程序,调用foo 输出2,遇到yield,协程返回状态和yield的参数 main true 4。

然后第二次resume,传递参数是“r”,这时候协程从上次yield的地方开始继续执行,也就是第一个local r的赋值,此时传递参数是字符串“r”,那么yield的参数就是“r”,local r的值就被赋值成了字符串。之后的x,y也同理

最后函数执行结束返回return之后,这时再去调用resume,因为程序已经结束了,所以是dead状态,返回false

这段程序的关键就在于,第一次之后每次resume的参数都作为上次挂起时候yield的返回值,可以在程序内继续赋值,相当于传递参数,而yield本身相当于是暂时性的return语句,yield本身的参数用来做resume函数的返回值,yield(a,b)也就相当于是return a,b

这就是之前很绕的一段话:resume的参数是yield的返回值,yield的参数是resume的返回值。真的太绕了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值