這是一段分析 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...