Lua是一種簡單,可擴展,可移植及高效的腳本語言。在嵌入式系統,移動設備,web服務器,游戲等方面都能見到它的身影。lua其中最吸引人的一點事它能很方便地與C語言或者其他語言。
這里說的是lua語言中的協同程序(coroute),也有人翻譯成為協作程序
基本函數和語法
coroutine就是lua的協同程序
先講一下coroutine的語法:
coroutine.create(
)
創建coroutine,返回coroutine, 參數是一個函數,當和resume配合使用的時候就喚醒函數調用
coroutine.resume(
)
重啟coroutine,和create配合使用
coroutine.yield()
掛起coroutine,將coroutine設置為掛起狀態,這個和resume配合使用能有很多有用的效果
coroutine.status(
)
查看coroutine的狀態
注:coroutine的狀態有三種:dead,suspend,running,具體什么時候有這樣的狀態請參考下面的程序
coroutine.wrap(
)
創建coroutine,返回一個函數,一旦你調用這個函數,就進入coroutine,和create功能重復
coroutine.running()
返回正在跑的coroutine,一個coroutine就是一個線程,當使用running的時候,就是返回一個corouting的線程號
使用下面的程序來了解一下這幾個函數的基本用法:
co = coroutine.create(
function(i)
print(i);
end
)
coroutine.resume(co, 1) -- 1
print(coroutine.status(co)) -- dead
print("----------")
co = coroutine.wrap(
function(i)
print(i);
end
)
co(1)
print("----------")
co2 = coroutine.create(
function()
for i=1,10 do
print(i)
if i == 3 then
print(coroutine.status(co2)) --running
print(coroutine.running()) --thread:XXXXXX
end
coroutine.yield()
end
end
)
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3
print(coroutine.status(co2)) -- suspended
print(coroutine.running()) --nil
print("----------")
返回數據:
coroutine.running就可以看出來,coroutine在底層實現就是一個線程。當create一個coroutine的時候就是在新線程中注冊了一個事件。當使用resume觸發事件的時候,create的coroutine函數就被執行了,當遇到yield的時候就代表掛起當前線程,等候再次resume觸發事件。
分析學習coroutine的時候經常遇到的一個程序
源程序可以看這里
我稍微做了點修改,增加了一下分隔符:
function foo (a)
print("foo", a) -- foo 2
return coroutine.yield(2 * a) -- return: a , b
end
co = coroutine.create(function (a , b)
print("co-body", a, b) -- co-body 1 10
local r = foo(a + 1)
print("co-body2", r)
local r, s = coroutine.yield(a + b, a - b)
print("co-body3", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10)) -- true, 4
print("------")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("------")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("------")
print("main", coroutine.resume(co, "x", "y")) -- false cannot resume dead coroutine
print("------")
這個程序返回:
很神奇,也很讓人看不懂
先理解下下面幾點:
- resume一定是在主線程的,yield是在子線程(coroutine)的
- resume可以帶參數
當coroutine是suspend狀態的時候,參數是作為coroutine的參數傳入的當coroutine是suspend狀態的時候,參數是作為coroutine的參數傳入的
- resume返回值有兩種情況
- 當coroutine是suspend狀態的時候,返回是是bool [yield params]
bool是這個resume操作是否成功yield params是當前coroutine的yield的參數
- 當coroutine是dead狀態的時候,返回值是bool [function return]
bool是這個resume操作是否成功yield params是當前coroutine的yield的參數
- 當coroutine是suspend狀態的時候,返回是是bool [yield params]
先對照上面幾條看一個簡單的例子:
co = coroutine.create(
function (a , b)
print("params", a, b)
return coroutine.yield(3, 3)
end
)
coroutine.resume(co, 1, 2);
print(coroutine.resume(co, 4, 5))
理解完上面這個程序,再看看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和yprint("co-body3", "x", "y")return b, "end" //此時coroutine線程結束,為dead狀態coroutine.resume(co, "x", "y") 返回值為 true 10 endprint("main" , true 10 end)
- print("main", coroutine.resume(co, "x", "y"))執行了:
由於coroutine.resume(co, "x", "y")已經dead了,所以這里返回false
參考文章
Luai: Lua reference manual interface: about
《lua程序設計》
本文基於署名-非商業性使用 3.0許可協議發布,歡迎轉載,演繹,但是必須保留本文的署名葉劍峰(包含鏈接http://www.cnblogs.com/yjf512/),且不得用於商業目的。如您有任何疑問或者授權方面的協商,請與我聯系。


