Lua协同程序函数coroutine使用实例

首页 > 脚本专栏 > Lua 更新日期: 2016-03-29
这篇文章主要介绍了Lua协同程序函数coroutine使用实例,协程是协同程序的简称,顾名思义,就是协同工作的程序,需要的朋友可以参考下

协程是协同程序的简称,顾名思义,就是协同工作的程序。协程拥有自己独立的桟、局部变量和PC计数器,同时又与其他协同程序共享全局变量和其他大部分东西;

协程与线程的主要区别在于,一个多线程程序可以同时运行几个线程(并发执行、抢占),而协同程序却需要彼此协作地运行,即一个多协程程序在任意时刻只能运行一个协程,并且正在执行的协程只会在其显式地要求挂起(suspend)时,它的执行才会暂停(无抢占、无并发)。

 Lua中所有与协程相关的函数都在coroutine(一个table)中; 函数create用于创建新的协程,只有一个参数——要执行的函数,返回一个thread类型的值。

thread的状态:suspend、running、dead、normal,可以通过coroutine.status(co)来检查co的状态。

创建一个thread时,它处于挂起状态。coroutine.resume函数用于启动或再次启动一个协程的执行,并可以向coroutine传递参数。当一个协程结束时,主函数返回的值将作为resume的返回值。

coroutine.yield用于一个运行中的协程挂起(suspend),之后可以再恢复(resume)。yield的返回值就是resume传入的参数。

Lua的协程模型可以类比Python的generator。

一个简单的示例:

代码如下:

> co = coroutine.create(function(a) while a > 0 do print(coroutine.yield(a)); a = a - 1; end return -1 end)
> return coroutine.resume(co, 3) --- 3是传递给主函数的
true        3
> return coroutine.resume(co, 4)
4
true        2
> return coroutine.resume(co, 5)
5
true        1
> return coroutine.resume(co, 6)
6
true        -1 ---主函数已经返回
> return coroutine.resume(co, 7)
false        cannot resume dead coroutine
>

协程的应用 —— 生产者/消费者

需求:输入一行,打印一行

代码如下:

function send(x)
coroutine.yield(x)
end
 
function receive(co)
local s, v = coroutine.resume(co)
return v
end
 
function producer()
return coroutine.create(function()
while true do
local x = io.read()
send(x)
end
end)
end
 
function filter(prod)
return coroutine.create(function()
for line = 1, math.huge do
local x = receive(prod)
x = string.format('%5d %s', line, x)
send(x)
end
end)
end
 
function consumer(prod)
while true do
local x = receive(prod)
io.write(x, '\n')
end
end
 
prod = producer()
fil = filter(prod)
con = consumer(fil)

协程的应用 —— 迭代器(类比Python Generator)
代码如下:

function seq_generator(n)
local i = 1
while i <= n do
coroutine.yield(i)
i = i + 1
end
return nil
end
 
function seq(n)
local co = coroutine.create(function() seq_generator(n) end)
return function()
local s,v = coroutine.resume(co)
return v
end
end
 
for i in seq(4) do
print(i)
end

执行
代码如下:

lua seq_generator.lua
1
2
3
4


> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!

相关文章
  • Lua协同程序COROUTINE运行步骤分解
    这篇文章主要介绍了Lua协同程序COROUTINE运行步骤分解,本文着重分解协同程序的运行步骤,需要的朋友可以参考下这是一段分析 lua 协程(协同程序,coroutine)的代码,来自 Lua reference manual interface (略有修改): 代码如下:function foo (a)    print("foo", ...
  • Lua之协同程序coroutine代码实例
    这篇文章主要介绍了Lua之协同程序coroutine代码实例,本文给出的代码示例较为复杂,需要对Lua协同程序有一定的了解方能看懂,需要的朋友可以参考下 do --create coroutine table --coroutine state: suspended, running, dead, normal --when create the corou ...
  • Lua常用时间函数使用实例
    这篇文章主要介绍了Lua常用时间函数使用实例,本文直接给出使用代码实例,并附有详细注释,要用到哪个复制即可,需要的朋友可以参考下 -- 获取当前的格林尼治时间 print(os.time()) -- 获取当前时间的字符串表示,形如:11/28/08 10:28:37 print(os.date()) -- 获取当前日期的字符串表示,形如:11/28/08 p ...
  • Lua中的函数代码实例
    这篇文章主要介绍了Lua中的函数代码实例,本文着重讲解函数的写法以及一些小知识,需要的朋友可以参考下在lua中,函数是一种"第一类值",它们具有特定的词法域. 第一类值:表示在lua中,函数与其他传统类型的值(数字和字符串)具有相同的权利,函数可以存储到变量中(无论全局变量还是局部变量)或者是table中,可以作为实参传递给其他函数,还可 ...
  • Lua之wrap函数用法示例
    这篇文章主要介绍了Lua之wrap函数用法示例,本文同时总结了wrap和Create的区别,需要的朋友可以参考下wrap和Create差不多,都是去创建一个coroutine,有些区别: 1,wrap不会通过resume去得到第一个返回值(错误信息)2,在创建完之后,直接调用函数,转到coroutine,而create却要resume才能转到coroutin ...
猜你喜欢