协程几乎是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 时传入的参数。这种参数传递的机制让可以结合前面传入的参数完成很多新的操作。
