蒐羅的關於Lua協程的幾個示例

2021-07-29 21:12:01 字數 3904 閱讀 3449

(1)coroutine.create (f)

傳乙個函式引數,用來建立協程。返回乙個「thread」物件。

(2)coroutine.isyieldable ()

如果正在執行的協程可以讓出,則返回真。值得注意的是,只有主協程(執行緒)和c函式中是無法讓出的。

(3)coroutine.resume (co [, val1, ···])

這是乙個非常重要的函式。用來啟動或再次啟動乙個協程,使其由掛起狀態變成執行狀態。

可以這麼說,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。如果協程aresume協程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 (···)

使正在執行的函式掛起。

傳遞給yeild的引數會作為resume的額外返回值。

同時,如果對該協程不是第一次執行resume,resume函式傳入的引數將會作為yield的返回值。

**

function

status

() print("co1's status :"..coroutine.status(co1).." ,co2's status: "..coroutine.status(co2))

endco1 = coroutine.create(function

( a )

print("arg is :"..a)

status()

local stat,rere = coroutine.resume(co2,"2")

print("resume's return is "..rere)

status()

local stat2,rere2 = coroutine.resume(co2,"4")

print("resume's return is "..rere2)

local arg = coroutine.yield("6")

end)

co2 = coroutine.create(function

( a )

print("arg is :"..a)

status()

local rey = coroutine.yield("3")

print("yeild's return is " .. rey)

status()

coroutine.yield("5")

end)

--主線程執行co1,傳入字串「main thread arg」

stat,mainre = coroutine.resume(co1,"1")

status()

print("last return is "..mainre)

用乙個函式status()輸出2個協程的狀態,最後輸出如下:

arg is :1

co1's status :running ,co2's status: suspended

arg is :2

co1's status :normal ,co2's status: running

resume's

returnis3

co1's status :running ,co2's status: suspended

yeild's

returnis4

co1's status :normal ,co2's status: running

resume's

returnis5

co1's status :suspended ,co2's status: suspended

last return

is6

生產者消費者模型

local newproductor

function

productor()

local i = 0

while

true

do i = i + 1

send(i) -- 將生產的物品傳送給消費者

endend

function

consumer()

while

true

dolocal i = receive() -- 從生產者那裡得到物品

print(i)

endendfunction

receive()

local status, value = coroutine.resume(newproductor)

return

value

endfunction

send(x)

coroutine.yield(x) -- x表示需要傳送的值,值返回以後,就掛起該協同程式

end-- 啟動程式

newproductor = coroutine.create(productor)

consumer()

輸出

123

4567

891011

1213

……

出處:

錢書康

Lua的協程基礎

參考 lua中的協同程式 coroutine 協同程式 coroutine 三個狀態 suspended 掛起,協同剛建立完成時或者yield之後 running 執行 dead 函式走完後的狀態,這時候不能再重新resume coroutine.create arg 根據乙個函式建立乙個協同程式,...

關於協程 nodejs和golang協程的不同

nodejs和golang都是支援協程的,從表現上來看,nodejs對於協程的支援在於async await,golang對協程的支援在於goroutine。關於協程的話題,簡單來說,可以看作是非搶占式的輕量級執行緒。一句話概括,上面提到了 可以看作是非搶占式的輕量級執行緒 在多執行緒中,把一段 放...

關於協程的 send None

這段時間太忙了,沒時間更新部落格。今天把python撿起來,看了下 協程。記錄乙個一開始沒太明白的點。直接貼 def consumer r j 0 while true n yield r 3 j j 1 print j d j if not n return print consumer cons...