Categories

Tags

Table of Contents

  1. coroutine.create
  2. coroutine.wrap
  3. coroutine.status

函数 参数 返回 说明
coroutine.create(f) 协程的函数定义 返回一个协程的控制器 创建一个新的协程
coroutine.resume(co,[var1,var2,…]) 第一个参数是协程控制器,后面的参数是控制器执行时需要的参数,是一个变长参数,可以传入任意多个 如果成功执行就返回true,接着的返回值是上一次调用协程时传入的参数。如果执行出错的话,就会返回false,以及错误信息 当第一次调用coroutine的resume方法时从主函数的第一行开始执行,之后调用时,会一直运行到终止或者遇到yield 函数
coroutine.yield(…) 传入变长参数 放回true 和 参数列表中的值  
coroutine.running() 返回当前正在执行的协程  
coroutine.status(co) 协程的控制句柄 返回当前协程的状态,有running,suspended,normal,dead  
coroutine.wrap(f) 协程的函数定义 返回一个协程的调用函数,相当于一个委托函数 wrap()也是用来创建协程的。不同的是,它不返回协程本身,而是返回一个函数,每次调用这个函数相当于执行resume()函数,调用这个函数是传入的参数相当于调用resume是传入的变长参数。和resume不同,它不是在保护模式下执行的,执行崩溃时会直接向外抛出
coroutine.isyieldable() 如果当前正在运行的协程可以让出,则返回true。    

例子一

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

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

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

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

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

 print("main", coroutine.resume(co, "x", "y"))
--[[
--输出
co-body	1	10
foo	2
main	true	4
-------
co-body	r
main	true	11	-9
-------
co-body	x	y
main	true	10	end
-------
main	false	cannot resume dead coroutine
--]]

例子二

进一步了解resume输入的参数有什么作用,因为初次调用时是从函数入口开始,所以作为函数的参数传递进来,后面就是从yield处开始,所以从yield 函数的返回值获取,从这里可以观察到yield的一些机制,coroutine.yield(...)负责挂起协程,并返回参数列表中的所有值给调用者,同时,它也会接收调用者通过coroutine.resume(co,...)传递进来的参数

function foo (_a)
   print("start corotine,a = ".._a)

   for i=1,_a do
   		print("yield return "..i.."------>")
   	  	local resumeInput = coroutine.yield(i)
   	  	print("<------resume begin",resumeInput)  
   end

 end

 co = coroutine.create(
 	foo
 )

local status = coroutine.status(co)
local a = 10
while status == "suspended" do
  	print("【main】 get return",coroutine.resume(co,a))
  	a = a + 1
  	status = coroutine.status(co)
end
--[[
start corotine,a = 10
yield return 1------>
【main】 get return	true	1
<------resume begin	11
yield return 2------>
【main】 get return	true	2
<------resume begin	12
yield return 3------>
【main】 get return	true	3
<------resume begin	13
yield return 4------>
【main】 get return	true	4
<------resume begin	14
yield return 5------>
【main】 get return	true	5
<------resume begin	15
yield return 6------>
【main】 get return	true	6
<------resume begin	16
yield return 7------>
【main】 get return	true	7
<------resume begin	17
yield return 8------>
【main】 get return	true	8
<------resume begin	18
yield return 9------>
【main】 get return	true	9
<------resume begin	19
yield return 10------>
【main】 get return	true	10
<------resume begin	20
【main】 get return	true
--]]

coroutine.create

使用create来创建协程

function Coroutine_Test01( a,b )
	print("resume args:"..a..","..b)
	yreturn = coroutine.yield()
	print(yreturn)
end

co =  coroutine.create(Coroutine_Test01)

print(coroutine.status(co))--suspended
coroutine.resume(co,111,222)--resume args:111,222
print(coroutine.status(co))--suspended
coroutine.resume(co,444,555)--444
print(coroutine.status(co))--dead

coroutine.resume(co,444,555)--444 因为yreturn = coroutine.yield()这里只接收一个参数,只打印了一个参数,所以coroutine.yield()是返回调用时输入的参数

coroutine.wrap

使用wrap来创建协程,可以发现,因为它返回的是函数,依次我们无法通过coroutine.status来获取其相关的状态

function Coroutine_Test01( a,b )
	print("resume args:"..a..","..b)
	yreturn = coroutine.yield()
	print(yreturn)
end

co = coroutine.wrap(Coroutine_Test01)

print(type(co))
co(111,222)-- 执行到yield处退出
print(a,b,c)
co(333)--从退出的地方继续,并返回调用是传入的参数
---co(444) -- 上一次调用中协程已经执行完毕,如果继续调用则会发生错误

coroutine.status

协程的状态

状态 说明  
suspended 挂起状态,刚创建完成时或者yield之后  
runing 运行状态 如果在协程的函数中调用status函数,传入自身句柄后,在执行到该语句时就会返回running状态
normal 如果协程Aresume协程B的时候,则协程A的状态为normal。在协程B执行的过程中协程A就一直处于normal状态,因为这时候它既不是挂起状态,也不是运行状态  
dead 结束状态,如果一个协程发生错误结束或者正常运行结束,那么就会进入dead状态,这时候如果调用resume的话就会返回false,且报错”cannot resume dead coroutine”  

参考