Lua協程(coroutine)程式執行分析

2022-09-21 02:18:07 字數 2762 閱讀 3134

這是一段分析 lua 協程(協同程式,coroutine)的**,來自 lua reference manual inte***ce (略有修改):

複製** **如下:

function foo (a)

print("foo", a)

return coroutine.yield(2*a)

endco = coroutine.create(function (a,b)

print("co-body1", a, b)

local r = foo(a+1)

print("co-body2", rundmcgmx)

local r, s = coroutine程式設計客棧.yield(a+b, a-b)

print("co-body3", r, s)

return b, "end"

end)

print("1----")

print("main", coroutine.resume(co, 1, 10))

print("2----")

print("main", coroutine.resume(co, "r"))

print("3----")

print("main", coroutine.resume(co, "x", "y"))

print("4----")

print("main", coroutine.resume(co, "x", "y"))

執行效果如下:

複製** **如下:

1------

co-body程式設計客棧1    1   10

foo 2

main    true    4

2------

co-body2    r

main    true    11  -9

3------

co-body3 &nwww.cppcns.combsp;  x   y

main    true    10  end

4------

main    false   cannot resume dead coroutine

這裡一共呼叫了 4 次 resume ,讓我們來看看它是怎麼執行的。

第一次:

複製** **如下:

print("main", coroutine.resume(co, 1, 10))

1.執行 print("co-body1", a, b) ,a 和 b 的值為 resume 提供,a=1, b=10 ;

2.計算 a+1=2 ,進入 foo(a) ,同時將剛才的計算結果通過 a 引數傳遞,執行 print("foo", a);

3.考慮 return coroutine.yield(2*a) ;

4.計算 2*a=4 ,碰到 yield,掛起 foo(a) 呼叫,將 4 返回給 resume 。注意,foo 的 return 還沒有執行;

5.resume 執行成功,返回 true, 4 。

第二次:

複製** **如下:

print("main", coroutine.resume(co, "r"))

1.從上一次掛起的 foo(a) 呼叫開始執行,接著執行沒有完成的 return 呼叫;

2.因為 yield 返回 resume 的呼叫引數,此時 foo(a+1) 程式設計客棧返回的值就是字串 "r"。這裡比較難理解。

因為大家可能會順理成章地認為 local r 這個變數的值應該是 yield(2*a) 中的 2*a 的值。

需要注意的是, yield 的返回值 與 yield 引數的值 是不同的。

前者你可以將其儲存在乙個變數中,或者 return 它,或者不使用它(不儲存 yield 的返回結果);後者則是 resume 的返回值。

3.執行 print("co-body2", r) ,r 的值為 "r" ;

4.考慮 local r, s = coroutine.yield(a+b, a-b) ;

5.計算 a+b=11, a-b=-9 ,碰到 yield ,掛起 co 的呼叫,將 11 和 9 返回給 resume 。注意,此時 local r, s 的賦值還沒有開始。

這裡不太好理解的是,為什麼 a 的值不是 "r" ?因為 "r" 已經被上面的 yield 的返回值給消費掉了。

6.resume 執行成功,返回 true, 11, -9 。

第三次:

複製** **如下:

print("main", coroutine.resume(co, "x", "y"))

1.從上一次 yield 的地方開始執行,接著執行沒有完成的 local r, s = 賦值。上面提到, yield 會返回 resume 的呼叫引數,因此 r 和 s 的值就是 "x" 和 "y" ;

2.執行 print("co-body3", r, s) 進行列印;

3.考慮 return b, "end" ;

4.b 的值一直都是 10 沒有變,這裡直接返回了,同時返回的還有 "end" 這個字串;

5.由於協程函式返回的時候,它的所有返回值都作為 resume 的返回值返回。因此這裡的 resume 執行成功,返回 10, "end" 。

第四次:

複製** **如下:

print("main", coroutine.resume(co, "x", "y"))

由於 co 函式已經返回,它處於 dead 狀態,不能 resume ,因此第 4 次 resume 失敗。

本文標題: lua協程(coroutine)程式執行分析

本文位址:

Lua中的協程coroutine簡介

lua中的協程coroutine lua中的協程有自己的堆疊,自己的區域性變數,有自己的指令指標,但是和其他協程程式共享全域性變數等資訊。任何時刻只有乙個協程程式在執行。並且這個在執行的協程只有明確被要求掛起時才會被掛起。建立乙個協程,引數是乙個function,作用如thread local c ...

python程式設計 9 協程 coroutine

def consumer r while true python的yield不但可以返回乙個值,他還可以接收呼叫者的發出的引數 n yield r 生成器,通過yield拿到訊息 n 並把結果返回r if not n return print consumer consuming s.n r 200...

yield實現 coroutine協程案例

yield可以手工實現協程,但python為我們封裝了乙個greenlet,先看看yield實現,yield需要手工操作,無法實現io操作時自動切換協程,greenlet是封裝好的,能方便使用io切換!importtime importqueue defconsumer name print sta...