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
(coroutine.status(co)) -- dead
(
"----------"
)
co = coroutine.wrap(
(i)
(i);
end
)
co(1)
)
co2 = coroutine.create(
()
for
i=1,10
do
(i)
if
i == 3 then
(coroutine.status(co2)) --running
(coroutine.running()) --thread:XXXXXX
end
coroutine.
yield
()
end
end
)
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3
(coroutine.status(co2)) -- suspended
(coroutine.running()) --nil
)
|
返回数据:
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)
"co-body"
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,a,b) -- co-body 1 10
local r = foo(a + 1)
"co-body2"
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,r)
local r,s = coroutine.yield(a + b,a - b)
"co-body3"
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,r,s)
b,
"end"
end)
"main"
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,coroutine.resume(co,1,10)) --
true
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,4
"------"
)
"r"
)) --
true
11 -9
"x"
"y"
10 end
)
false
cannot resume dead coroutine
这个程序返回:
很神奇,也很让人看不懂
先理解下下面几点:
- resume一定是在主线程的,yield是在子线程(coroutine)的
- resume可以带参数
当coroutine是suspend状态的时候,参数是作为coroutine的参数传入的
当coroutine是suspend状态的时候,参数是作为coroutine的参数传入的
- resume返回值有两种情况
- 当coroutine是suspend状态的时候,返回是是bool [yield params]
bool是这个resume操作是否成功
yield p
arams是当前coroutine的yield的参数
- 当coroutine是dead状态的时候,返回值是bool [function return]
bool是这个resume操作是否成功
yield p
arams是当前coroutine的yield的参数
先对照上面几条看一个简单的例子:
co = coroutine.create(
function (a,b)
"params"
ottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; Box-sizing: content-Box !important; font-family: Consolas,b)
coroutine.yield(3,3)
end
)
ottom-right-radius: 0px !important; border-b
ottom-left-radius: 0px !important; background-image: none !important; background-color: rgb(244,2);
print(coroutine.resume(co,4,5))
理解完上面这个程序,再看看coroutine2的程序,这里把每个输出执行了哪些步骤列出来了:
- print("main",10)) 执行了:
print("co-body",10)
print("foo",2)
coroutine.resume(co,10) 返回 true,4 (!!这里的4是yield的参数)
print("main",true,4)
- print("main","r")) 执行了:
foo(a) 返回了 "r" (这是由yield返回的)
print("co-body2","r")
coroutine.resume(co,"r") 返回 true,11 -9 (!!这里的a和b还是用1和10计算的)
print("main",11 -9)
- print("main","x","y"))执行了:
local r,a - b) r和s值为x和y
print("co-body3","y")
return b,"end" //此时coroutine线程结束,为dead状态
coroutine.resume(co,"y") 返回值为 true 10 end
print("main",true 10 end)
- print("main","y"))执行了:
由于coroutine.resume(co,"y")已经dead了,所以这里返回false
相关文章
1.github代码实践源代码是lua脚本语言,下载th之后运行thmai...
此文为搬运帖,原帖地址https://www.cnblogs.com/zwywilliam/...
Rime输入法通过定义lua文件,可以实现获取当前时间日期的功能...
localfunctiongenerate_action(params)localscale_action=cc...
2022年1月11日13:57:45 官方:https://opm.openresty.org/官...
在Lua中的table(表),就像c#中的HashMap(哈希表),key和...