lua中协程的学习(一)

在书《Lua程序设计(第4版)》的协程一章,第273-274页,书上有个例子,让我困惑不已,后来把之前看到的一篇博客——Lua的协程和协程库详解
反复看了两遍,自己动手写了demo测试,才解开心中的疑惑,特此记录,以帮助同样遇到困惑的朋友。

函数coroutine.resume (co [, val1, ···])用来启动或再次启动一个协程,使其由挂起状态变成运行状态。
resume函数相当于在执行协程中的方法。参数Val1…是执行协程co时传递给协程的方法。
  1)、首次执行协程co时,参数Val1…会传递给协程co的函数;
  2)、再次执行协程co时,参数Val1…会作为给协程co中上一次yeild的返回值。
  这是协程的核心。如果没理解也不用急,继续往下看,稍后我会详细解释。

resume函数返回什么呢?有3种情况:   
  1)、如果协程co的函数执行完毕,协程正常终止,resume 返回 true和函数的返回值。
  2)、如果协程co的函数执行过程中,协程让出了(调用了yeild()方法),那么resume返回true和协程中调用yeild传入的参数。
  3)、如果协程co的函数执行过程中发生错误,resume返回false与错误消息。

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

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

书上的例子是这样:
例一

co = coroutine.create(function(x)
	print("co1", x)
	print("co2", coroutine.yield())
end)

coroutine.resume(co, "hi")
coroutine.resume(co, 4, 5)

运行结果:

co1	hi
co2	4	5

看到这里,貌似没有问题。
但是如果是这样:
例二

co = coroutine.create(function(x)
	print("co1", x)
	print("co2", coroutine.yield(1, 2))
end)

coroutine.resume(co, "hi")
coroutine.resume(co, 4, 5)

运行结果:

co1	hi
co2	4	5

明明这里有coroutine.yield(1, 2),这个参数1和2,怎么好像没生效一样?

不急,我们来看例三:

co = coroutine.create(function(x)
	print("co1", x)
	print("co2", coroutine.yield(1, 2))
end)

print(coroutine.resume(co, "hi"))
print(coroutine.resume(co, 4, 5))

运行结果:

co1	hi
true	1	2
co2	4	5
true

1和2出现了,为了更好地解释,我们将其改成功能相同的例四:

co = coroutine.create(function(x)
	print("co1", x)
	ret1, ret2 = coroutine.yield(1, 2)
	print("co2", ret1, ret2)
end)

print(coroutine.resume(co, "hi"))
print(coroutine.resume(co, 4, 5))

运行结果和例三相同,这时候,我们再来解释,就清楚了。

  1. coroutine.resume(co, “hi”)
  2. 此时是第一个resume,参数会直接传到到co = coroutine.create(function(x)
    print(“co1”, x),输出co1 hi,
  3. 继续执行ret1, ret2 = coroutine.yield(1, 2),先看右边coroutine.yield(1, 2),这时候程序在这里返回给resume,返回值为true 1 2,print(coroutine.resume(co, “hi”))执行print,打印出true 1 2
  4. coroutine.resume(co, 4, 5),第二个coroutine.resume来了,从ret1, ret2 = coroutine.yield(1, 2)开始执行,上一步coroutine.yield(1, 2)已经返回给第一个resume了,此时的coroutine.yield获得的参数是coroutine.resume(co, 4, 5)中的4和5,所以ret1, ret2 = 4, 5
    print(“co2”, ret1, ret2)打印出的co2 4 5
  5. 至此co = coroutine.create(function(x) 中间省略 end),这里的function(x)已经全部执行完毕,co正常结束,返回true,除此外没有其他返回值,print(coroutine.resume(co, 4, 5)),执行print函数,打印出true。

我们将它拆解开,才完全理清了参数传递过程。原来书中写的例子有些不清不楚,看来一个好的例子能更好地释疑。

参考:
Lua的协程和协程库详解
理解Lua中最强大的特性-coroutine(协程)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值