協程的建立
--協同程式(協程)
--協程的建立
--常用方法
--通過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的前面