天天看點

Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

協程的建立

--協同程式(協程)
--協程的建立
--常用方法
--通過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))
--建立出來的不是線程類型而是函數           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

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() --因為其本質就是函數,直接調就完事了           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

協程的挂起(關鍵)

--協程挂起
fun2 = function()
    --先弄一個死循環
    while true do
        print(123)
        --下面這個就是協程的挂起函數
        coroutine.yield()--讓其處于一個挂起的狀态
    end
end

co3 = coroutine.create(fun2)
coroutine.resume(co3)           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

上面的協程隻執行了一次

這個跟我們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)           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

從上面就可以很直覺的看到,每執行一次Coroutine.resume()啟動協程,協程就在前一次的基礎上,繼續運算

我們在用coroutine.wrap()試下,原理也是一樣的

Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

結果也是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)           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

預設第一個傳回值是協程是否啟動成功,第二個是yield裡面的傳回值

我們再看看用coroutine.wrap()下的情況

Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态

使用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)) -- 協程結束           
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态
  • 這個函數可以獲得目前正在 運作的協程的線程号

    coroutine.running()

這個想要列印得放在協程裡面,并且在yeild的前面

Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态
Lua協同程式(協程)協程的建立協程的運作協程的挂起(關鍵)協程的狀态