lua是一種簡單,可擴充,可移植及高效的腳本語言。在嵌入式系統,移動裝置,web伺服器,遊戲等方面都能見到它的身影。lua其中最吸引人的一點事它能很友善地與c語言或者其他語言。
這裡說的是lua語言中的協同程式(coroute),也有人翻譯成為協作程式
coroutine就是lua的協同程式
建立coroutine,傳回coroutine, 參數是一個函數,當和resume配合使用的時候就喚醒函數調用
重新開機coroutine,和create配合使用
挂起coroutine,将coroutine設定為挂起狀态,這個和resume配合使用能有很多有用的效果
檢視coroutine的狀态
注:coroutine的狀态有三種:dead,suspend,running,具體什麼時候有這樣的狀态請參考下面的程式
建立coroutine,傳回一個函數,一旦你調用這個函數,就進入coroutine,和create功能重複
傳回正在跑的coroutine,一個coroutine就是一個線程,當使用running的時候,就是傳回一個corouting的線程号
<code>co = coroutine.create(</code>
<code> </code><code>function</code><code>(i)</code>
<code> </code><code>print</code><code>(i);</code>
<code> </code><code>end</code>
<code>)</code>
<code>coroutine.resume(co, 1) -- 1</code>
<code>print</code><code>(coroutine.status(co)) -- dead</code>
<code>print</code><code>(</code><code>"----------"</code><code>)</code>
<code>co = coroutine.wrap(</code>
<code>co(1)</code>
<code>co2 = coroutine.create(</code>
<code> </code><code>function</code><code>()</code>
<code> </code><code>for</code> <code>i=1,10</code><code>do</code>
<code> </code><code>print</code><code>(i)</code>
<code> </code><code>if</code> <code>i == 3 then</code>
<code> </code><code>print</code><code>(coroutine.status(co2)) --running</code>
<code> </code><code>print</code><code>(coroutine.running()) --thread:xxxxxx</code>
<code> </code><code>end</code>
<code> </code><code>coroutine.</code><code>yield</code><code>()</code>
<code> </code><code>end</code>
<code>coroutine.resume(co2) --1</code>
<code>coroutine.resume(co2) --2</code>
<code>coroutine.resume(co2) --3</code>
<code>print</code><code>(coroutine.status(co2)) -- suspended</code>
<code>print</code><code>(coroutine.running()) --nil</code>
傳回資料:

coroutine.running就可以看出來,coroutine在底層實作就是一個線程。當create一個coroutine的時候就是在新線程中注冊了一個事件。當使用resume觸發事件的時候,create的coroutine函數就被執行了,當遇到yield的時候就代表挂起目前線程,等候再次resume觸發事件。
我稍微做了點修改,增加了一下分隔符:
<code>function foo (a)</code>
<code> </code><code>print(</code><code>"foo"</code><code>, a) -- foo 2</code>
<code> </code><code>return</code> <code>coroutine.yield(2 * a) --</code><code>return</code><code>: a , b</code>
<code>end</code>
<code>co = coroutine.create(function (a , b)</code>
<code> </code><code>print(</code><code>"co-body"</code><code>, a, b) -- co-body 1 10</code>
<code> </code><code>local r = foo(a + 1)</code>
<code> </code>
<code> </code><code>print(</code><code>"co-body2"</code><code>, r)</code>
<code> </code><code>local r, s = coroutine.yield(a + b, a - b)</code>
<code> </code><code>print(</code><code>"co-body3"</code><code>, r, s)</code>
<code> </code><code>return</code> <code>b,</code><code>"end"</code>
<code>end)</code>
<code> </code>
<code>print(</code><code>"main"</code><code>, coroutine.resume(co, 1, 10)) --</code><code>true</code><code>, 4</code>
<code>print(</code><code>"------"</code><code>)</code>
<code>print(</code><code>"main"</code><code>, coroutine.resume(co,</code><code>"r"</code><code>)) --</code><code>true</code> <code>11 -9</code>
<code>print(</code><code>"main"</code><code>, coroutine.resume(co,</code><code>"x"</code><code>,</code><code>"y"</code><code>)) --</code><code>true</code> <code>10 end</code>
<code>print(</code><code>"main"</code><code>, coroutine.resume(co,</code><code>"x"</code><code>,</code><code>"y"</code><code>)) --</code><code>false</code> <code>cannot resume dead coroutine</code>
這個程式傳回:
很神奇,也很讓人看不懂
先了解下下面幾點:
resume一定是在主線程的,yield是在子線程(coroutine)的
resume可以帶參數
當coroutine是suspend狀态的時候,參數是作為coroutine的參數傳入的
resume傳回值有兩種情況
當coroutine是suspend狀态的時候,傳回是是bool [yield params]
bool是這個resume操作是否成功
yield params是目前coroutine的yield的參數
當coroutine是dead狀态的時候,傳回值是bool [function return]
先對照上面幾條看一個簡單的例子:
<code> </code><code>function (a , b)</code>
<code> </code><code>print(</code><code>"params"</code><code>, a, b)</code>
<code> </code><code>return</code> <code>coroutine.yield(3, 3)</code>
<code>coroutine.resume(co, 1, 2);</code>
<code>print(coroutine.resume(co, 4, 5))</code>
了解完上面這個程式,再看看coroutine2的程式,這裡把每個輸出執行了哪些步驟列出來了:
print("main", coroutine.resume(co, 1, 10)) 執行了:
print("co-body", 1, 10)
print("foo", 2)
coroutine.resume(co, 1, 10) 傳回 true, 4 (!!這裡的4是yield的參數)
print("main", true, 4)
print("main", coroutine.resume(co, "r")) 執行了:
foo(a) 傳回了 "r" (這是由yield傳回的)
print("co-body2", "r")
coroutine.resume(co, "r") 傳回 true, 11 -9 (!!這裡的a和b還是用1和10計算的)
print("main" , true, 11 -9)
print("main", coroutine.resume(co, "x", "y"))執行了:
local r, s = coroutine.yield(a + b, a - b) r和s值為x和y
print("co-body3", "x", "y")
return b, "end" //此時coroutine線程結束,為dead狀态
coroutine.resume(co, "x", "y") 傳回值為 true 10 end
print("main" , true 10 end)
由于coroutine.resume(co, "x", "y")已經dead了,是以這裡傳回false