协程
多线程的概念:从软件或者硬件上实现多个线程并发执行的技术。同一时间执行多于一个线程,这时候就会产生资源竞争等
协程的概念:相互之间以同步的方式彼此协作。可以看成是单线程的多个函数相互调用,但是又有一点点的不同
lua不支持多线程,只支持协程的运行方式
如下则是lua协程的类似调用过程(假设A是主线程,B和C是协程)
A执行三分之一,调用B
B执行四分之一,调用C
C执行五分之一,挂起(C挂起之后,则调用C的B会继续自行接下去的函数)
B执行到三分之二,挂起(B挂起之后,则A会继续从三分之一的位置开始执行)
A执行到二分之一,调用C(之前C已经执行到了五分之一的位置,则C继续从五分之一的位置继续执行下去)
C执行到五分之二,挂起(C挂起之后,则A会继续从二分之一的位置开始执行)(因为之前是A调用的C)
。
。
。
如上所述的调用过程可以看出整个过程不会涉及到抢占和并发的情况,均是同步执行
1 print("Start A") 2 3 -- 开始可以先创建两个协程B和C 4 local C = coroutine.create(function(parentT) 5 print("Start C from:" .. parentT) 6 print ("process C to 1/5") 7 local ret = coroutine.yield("C") 8 print ("continue C, from : " .. ret) 9 print ("end C") 10 11 -- 返回结果,跟yield(args)是一样的; 返回给最近一次resume本协程的协程 12 return "end C" 13 end) 14 15 local B = coroutine.create(function() 16 print("Start B") 17 18 print ("process B to 1/3") 19 local ret, val = coroutine.resume(C, "B") 20 print ("continue B, get C ret is " .. val) 21 print ("process B to 2/3") 22 local ret = coroutine.yield("B") -- 参数的传入跟返回均可以多个 23 print ("continue B, from :" .. ret) 24 end) 25 26 print("process A to 1/3") 27 local ret, val = coroutine.resume(B) 28 print("continue A, get " .. val) 29 print("process A to 1/2") 30 local ret, val = coroutine.resume(C, "A") 31 print("continue A, get ret:" .. val) 32 print("end A")
如上所述的代码;执行完之后,显示如下的结果
Start A process A to 1/3 Start B process B to 1/3 Start C from:B process C to 1/5 continue B, get C ret is C process B to 2/3 continue A, get B process A to 1/2 continue C, from : A end C continue A, get ret:end C end A
如上可以看出协程的调用方式
如上当coroutine.resume的时候,返回至少一个;ret跟其他的值;其他的值是yield传进去的参数;ret的值则是此次的resume是否调用成功
并且协程里面的异常不会传导到外面的调用;只会返回ret为false,第二个返回结果为错误的原因(可以给它设置个异常即可看出来,如:assert(false) )
其他:
1、可以查看每个协程当前的状态如:coroutine.status(B)
2、判断当前的协程是否可以挂起:coroutine.isyieldable()
3、还有一个功能跟coroutine.create() 类似的调用 coroutine.wrap() 该功能是以装饰的方式执行
如: A = coroutine.create(.....) 则要将A唤醒需要调用coroutine.resume(A)
但是如果使用A = coroutine.wrap(。。。) 则要将A唤醒只需要执行A() ;跟普通的函数调用一样,但是这里如果执行A的时候发生了异常,则会传到到外面