Lua 支持 coroutine ,這個東西也被稱爲協同式多線程 (collaborative multithreading) 。 Lua 爲每一個 coroutine 提供一個獨立的運行線路。 然而和多線程系統中的線程不一樣,coroutine 只在顯式的調用了 yield 函數時纔會掛起。html
建立一個 coroutine 須要調用一次 coroutine.create
。 它只接收單個參數,這個參數是 coroutine 的主函數。 create
函數僅僅建立一個新的 coroutine 而後返回它的控制器 (一個類型爲 thread 的對象); 它並不會啓動 coroutine 的運行。多線程
當你第一次調用 coroutine.resume
時, 所需傳入的第一個參數就是 coroutine.create
的返回值。 這時,coroutine 從主函數的第一行開始運行。 接下來傳入 coroutine.resume
的參數將被傳進 coroutine 的主函數。 在 coroutine 開始運行後,它講運行到自身終止或是遇到一個 yields 。函數
coroutine 能夠經過兩種方式來終止運行: 一種是正常退出,指它的主函數返回(最後一條指令被運行後,不管有沒有顯式的返回指令); 另外一種是非正常退出,它發生在未保護的錯誤發生的時候。 第一種狀況中,coroutine.resume
返回 true , 接下來會跟着 coroutine 主函數的一系列返回值。 第二種發生錯誤的狀況下, coroutine.resume
返回 false , 緊接着是一條錯誤信息。lua
coroutine 中切換出去,能夠調用 coroutine.yield
。 當 coroutine 切出,與之配合的 coroutine.resume
就當即返回, 甚至在 yield 發生在內層的函數調用中也能夠(就是說, 這不限於發生在主函數中,也能夠是主函數直接或間接調用的某個函數裏)。 在 yield 的狀況下,coroutine.resume
也是返回 true, 緊跟着那些被傳入 coroutine.yield
的參數。 等到下次你在繼續一樣的 coroutine ,將從調用 yield 的斷點處運行下去。 斷點處 yield 的返回值將是 coroutine.resume
傳入的參數。spa
相似 coroutine.create
, coroutine.wrap
這個函數也將建立一個 coroutine , 可是它並不返回 coroutine 自己,而是返回一個函數取而代之。一旦你調用這個返回函數,就會切入 coroutine 運行。 全部傳入這個函數的參數等同於傳入 coroutine.resume
的參數。 coroutine.wrap
會返回全部應該由除第一個(錯誤代碼的那個布爾量) 以外的由 coroutine.resume
返回的值。 和 coroutine.resume
不一樣, coroutine.wrap
不捕獲任何錯誤; 全部的錯誤都應該由調用者本身傳遞。線程
看下面這段代碼展現的一個例子:code
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"))
當你運行它,將獲得以下輸出結果:orm
co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine