协程几乎是lua语言最亮的一个语法点!python的生成器也借鉴了该语法点,接下来我们来看下神奇的协程。
--http://vizlabxt.github.io/blog/2014/02/04/Lua-Corutine/
--coroutine.create(f):用函数 f 创建一个协程,返回 thread 类型对象。
co01=coroutine.create(function() print("hi") end)
print(co01,type(co01))
--coroutine有四种状态:
--suspend,dead,running,normal
--suspend:当coroutine被创建时,是suspend状态
print(coroutine.status(co01)) -->suspend
--resume方法会执行coroutine任务,状态会变为running
coroutine.resume(co01) -->hi
--coroutine执行完成后,状态变为dead
print(coroutine.status(co01)) -->dead
--dead之后不能resume了
print(coroutine.resume(co01)) -->false cannot resume dead coroutine
co02=coroutine.create(function()
for i=1,10 do
print("coroutine",i)
print("yield",coroutine.yield())
end
end)
yield可以中断coroutine的执行,打印结果如下:
thread: 0x5625362f7b68 thread
suspended
hi
dead
false cannot resume dead coroutine
coroutine 1
如果将上面代码中的
print("yield",coroutine.yield())
注释掉,则会全部执行co02协程:
thread: 0x56360e328b68 thread
suspended
hi
dead
false cannot resume dead coroutine
coroutine 1
coroutine 2
coroutine 3
coroutine 4
coroutine 5
coroutine 6
coroutine 7
coroutine 8
coroutine 9
coroutine 10
如果想保留yield关键字,那么resume10次之后的效果也一样:
co02=coroutine.create(function()
for i=1,10 do
print("coroutine",i)
print("yield",coroutine.yield())
end
end)
for i=1,10 do
coroutine.resume(co02)
end
从coroutine的角度出发,当co02 suspend时,co02在试行yield的操作,当yield执行完后,再会在执行co02的操作。
这意味着,当co02被suspend时,stack上的参数传递给yield继续执行,yield执行完后,再将参数交给co02的stack!
我们使用 resume 函数继续执行协程,用 yield 函数挂起协程。
在下一次调用 resume 时如何为协程传入参数:
从例子中可以看到,coroutine.yield 函数返回后的值即是第二次调用 resume 时传入的参数。这种参数传递的机制让可以结合前面传入的参数完成很多新的操作。