协程的创建
--协同程序(协程)
--协程的创建
--常用方法
--通过coroutine.create()
fun = function()
print(666)
end
--创建协程会有一个返回值,声明一个变量去接收
co = coroutine.create(fun)
print(co)
print(type(co))--类型线程
--第二种方法
--coroutine.wrap()
co2= coroutine.wrap(fun)
print(co2)
print(type(co2))
--创建出来的不是线程类型而是函数
thread 指代协程(thread 是线程的意思,协程的本质还是线程对象。协程在lua内也是一个变量类型)
00DAC208 指协程的地址
协程的运行
--协程运行
fun = function()
print(666)
end
co = coroutine.create(fun)
co2= coroutine.wrap(fun)
--这是协程运行的第一种方式,对应运行通过coroutine.create()创建出来的协程
coroutine.resume(co)
--第二种方式 对应通过coroutine.wrap()创建出来的协程
co2() --因为其本质就是函数,直接调就完事了
协程的挂起(关键)
--协程挂起
fun2 = function()
--先弄一个死循环
while true do
print(123)
--下面这个就是协程的挂起函数
coroutine.yield()--让其处于一个挂起的状态
end
end
co3 = coroutine.create(fun2)
coroutine.resume(co3)
上面的协程只执行了一次
这个跟我们C#中的是不是不大一样
在C#中我们一旦启动了协程,它就会隔一帧或者几帧执行一次
但lua中很不一样,lua的代码是从上到下只执行一次的,没有循环的概念
因此每启动一次协程,只会启动一次协程函数,然后进去碰到yield就处于挂起状态
如果想要多次执行。就需要多次启动
每重新启动一次协程,就相当于在协程里的函数又跑了一次,可以理解为暂停/播放
为了更加直观一点,我们可以给上面的函数改造一下
fun2 = function()
--先弄一个死循环
local x = 0
while true do
x=x+1
print(x)
--下面这个就是协程的挂起函数
coroutine.yield()--让其处于一个挂起的状态
end
end
co3 = coroutine.create(fun2)
coroutine.resume(co3)
coroutine.resume(co3)
coroutine.resume(co3)
从上面就可以很直观的看到,每执行一次Coroutine.resume()启动协程,协程就在前一次的基础上,继续运算
我们在用coroutine.wrap()试下,原理也是一样的
结果也是123
yield是可以有返回值的
我们接着来进行操作
fun4 = function()
local x = 1
while true do
print(x)
x=x+1
-- 协程挂起函数
coroutine.yield(x) --在yield上加x
end
end
co4 = coroutine.create(fun4)
isTrue,tempI=coroutine.resume(co4) -- 搞一个参数接住它
print(isTrue,tempI)
默认第一个返回值是协程是否启动成功,第二个是yield里面的返回值
我们再看看用coroutine.wrap()下的情况使用coroutine.wrap()进行协程调用也可以有返回值 只是没有默认的第一个返回的布尔值
协程的状态
coroutine.status 协程对象
- dead 结束
- suspended 暂停 (只要挂起(yeild)就认为这个协程暂停))
- running 进行中
funStop = function()
print('end')
end
fun5 = function()
local x = 1
while true do
print(x)
x=x+1
print(coroutine.status(co5)) --协程运行中
coroutine.yield(x)
end
end
co5 = coroutine.create(fun5)
coroutine.resume(co5)
print(coroutine.status(co5)) -- 协程暂停(有yield)
co6 = coroutine.create(funStop)
coroutine.resume(co6)
print(coroutine.status(co6)) -- 协程结束
- 这个函数可以获得当前正在 运行的协程的线程号
coroutine.running()
这个想要打印得放在协程里面,并且在yeild的前面