1. 程式人生 > >Lua coroutine協程

Lua coroutine協程

coroutine:
coroutine.create    --返回thread物件
coroutine.isyieldable
coroutine.resume 
coroutine.running  
coroutine.status
coroutine.wrap      --返回function物件
coroutine.yield 

(1)coroutine.create (func)
  傳入一個函式引數,用來建立協程。返回一個“thread”物件。

(2)coroutine.isyieldable ()
  如果正在執行的協程可以讓出,則返回真。注意:只有主協程(執行緒)和C函式中是無法讓出的。

(3
)coroutine.resume (co [, val1, ···]) 用來啟動或再次啟動一個協程,使其由掛起狀態變成執行狀態。coroutine.resume函式相當於執行協程中的方法。引數Val1...是執行協程co時傳遞給協程的方法。 首次執行協程co時,引數Val1...會傳遞給協程co的函式; 再次執行協程co時,引數Val1...會作為給協程co中上一次yeild的返回值。   resume函式返回什麼呢?有3種情況:   1)、如果協程co的函式執行完畢,協程正常終止,resume 返回 true和函式的返回值。   2)、如果協程co的函式執行過程中,協程讓出了(呼叫了yeild()方法),那麼resume返回true
和協程中呼叫yeild傳入的引數。   3)、如果協程co的函式執行過程中發生錯誤,resume返回false與錯誤訊息。   可以看到resume無論如何都不會導致程式崩潰。它是在保護模式下執行的。 (4)coroutine.running () 用來判斷當前執行的協程是不是主執行緒,如果是,就返回true。 (5)coroutine.status (co)   返回一個字串,表示協程的狀態。有4種狀態:   1)、running。如果在協程的函式中呼叫status,傳入協程自身的控制代碼,那麼執行到這裡的時候才會返回running狀態。   2)、suspended。如果協程還未結束,即自身呼叫了yeild或還沒開始執行,那麼就是suspended狀態。   3
)、normal。如果協程A resume協程B時,協程A處於的狀態為normal。在協程B的執行過程中,協程A就一直處於normal狀態。因為它這時候既不是掛起狀態、也不是執行狀態。   4)、dead。如果一個協程發生錯誤結束,或正常終止。那麼就處於dead狀態。如果這時候對它呼叫resume,將返回false和錯誤訊息。 (6)coroutine.wrap (f)   wrap()也是用來建立協程的。只不過這個協程的控制代碼是隱藏的。跟create()的區別在於:   1)、wrap()返回的是一個函式,每次呼叫這個函式相當於呼叫coroutine.resume()。   2)、呼叫這個函式相當於在執行resume()函式。   3)、呼叫這個函式時傳入的引數,就相當於在呼叫resume時傳入的除協程的控制代碼外的其他引數。   4)、呼叫這個函式時,跟resume不同的是,它並不是在保護模式下執行的,若執行崩潰會直接向外丟擲。 (7)coroutine.yield (···)   使正在執行的函式掛起,可以傳入變長引數。
#!/usr/local/bin/lua

function func(a, b)
        while a > 0 do
                print(a + b)
                print("running:", coroutine.isyieldable())
                a = a-1

                if a < 50 then
                        y = coroutine.yield(80, 2)
                        print(y)
                end
        end
end


co1 = coroutine.create(func)
print(co1)

print(coroutine.status(co1))
coroutine.resume(co1, 100, 1)
print(coroutine.status(co1))                      
#!/usr/local/bin/lua
co2 = coroutine.wrap(function (a, b)
    print("resume :", a, b)
    ret = coroutine.yield()
    print("ret:", ret)
end)

print(type(co2))
print(co2)
co2(2,3)
co2(88)

--程式執行結果
function
function: 0x135b6c0
resume :    2   3
ret:    88
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("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))

例程:

#!/usr/local/bin/lua

print("========coroutine.create==============")
function f(a, b, c)
    print("a + b + c=", a+b+c)
end

co = coroutine.create(f)
print(type(co))
print(co)
print(coroutine.resume(co, 2, 4, 6))
print(coroutine.status(co))

print("========coroutine.wrap==========")
function g(a, b ,c)
    print("a * b * c=", a*b*c)
end

co1 = coroutine.wrap(g)
print(type(co1))
print(co1)
print(co1(2,3,4))


--程式執行結果
========coroutine.create==============
thread
thread: 0x1475638
a + b + c=  12
true
dead
========coroutine.wrap==========
function
function: 0x147cbe0
a * b * c=  24