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

协程是协同程序的简称,顾名思义,就是协同工作的程序。协程拥有自己独立的桟、局部变量和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

时间: 2024-09-01 14:49:42

Lua协同程序函数coroutine使用实例_Lua的相关文章

Lua协同程序(COROUTINE)运行步骤分解_Lua

这是一段分析 lua 协程(协同程序,coroutine)的代码,来自 Lua reference manual interface (略有修改): 复制代码 代码如下: function foo (a)     print("foo", a)     return coroutine.yield(2*a) end co = coroutine.create(function (a,b)    print("co-body1", a, b)    local r =

Lua之协同程序coroutine代码实例_Lua

do --create coroutine table --coroutine state: suspended, running, dead, normal --when create the coroutine, the status is suspended, After calling it, the status is dead --get the coroutine status by the way coroutine.status local coA = 0; local coB

Lua中的函数精讲笔记_Lua

函数的用途: 1.完成指定的任务,这种情况下作为调用语句使用. 2.计算并返回值,这种情况下,函数作为赋值语句的表达式使用. 函数的参数为空,必须使用()表示函数调用.例外:当函数只有一个参数,并且这个参数是字符串或表构造时,()是可选的. lua提供了面向对象调用函数的语法 o:foo(x)与o.f(o,x)是等价的. lua函数的实参与形参的匹配与赋值语句类似,多余部分被忽略,缺少部分nil补足. lua函数可以返回多个值,return后列出要返回值的列表即可返回多值 复制代码 代码如下:

Lua中的__index和__newindex实例_Lua

前言 这篇博文将通过几个简单的实例演示,巩固对__index和__newindex的理解,同时加深对Lua中元表和元方法的理解,如果对Lua的元表和元方法还不是很熟悉的话,请参考这篇文章:<Lua中的元表与元方法>. 具有默认值的table 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: 复制代码 代码如下: function setDefault(tb, defaultValue)      local mt = {__index

Lua中的类编程代码实例_Lua

Lua的类有点像javascript,但是更简明灵活,table即对象,对象就是类.Metatables比起ruby里的MetaClass更加好用,缺点是实例化和继承的代码有点多, 不像ruby里的"<"和"<<",继承链就是查找方法时的方法链. Account={ test1=function(a) print("Account test1") end } Account.test2=function(a) print(&qu

Lua中的函数写法简明示例_Lua

函数定义:用关键字function定义函数,以关键字end结束 局部变量:用关键字local定义.如果没有用local定义,即使在函数内部定义定义的变量也是全局变量! 函数可以有多个返回值:return a,b,c... 平行赋值:a,b=c,d 全局变量:前面的代码定义了三个全局变量:foo,r1,r2 这是我写的第一个Lua函数: 复制代码 代码如下: function foo(a,b,c)      local sum=a+b      return sum,c  --函数可以有多个返回值

Lua中简单的错误处理实例_Lua

昨天遇到另外一位独立游戏开发者,所以多聊了一会,然后-然后就没有看书了.(小若:借口!借口!)   今天来聊聊错误处理吧,不过毕竟这只是前面的章节,书上的内容似乎有点一笔带过的味道. 没关系,简单更好~ 1.红色警报--error 我们应该能经常看到类似以下的错误信息: 复制代码 代码如下: [LUA-print] LUA ERROR: [string "src/main.lua"]:108: [string "src/main.lua"]:89: attempt

Lua table的concat方法使用实例_Lua

一部分的table函数只对其数组部分产生影响, 而另一部分则对整个table均产生影响. 下面会分开说明. 复制代码 代码如下: table.concat(table, sep,  start, end) concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开.除了table外, 其他的参数都不是必须的, 分隔符的默认值是空字符, start的默认

Lua中使用二维数组实例_Lua

在Lua中跟JS也是一样,没有二维数组的概念,但是二维数组对我们的开发又是极其的重要,当然,使用很多啦.谈谈在Lua中如何使用二维数组? 原理,一维数组里面给一个嵌套就是二维数组了,好,就那么简单,看看代码更容易理解 最近在做一个项目,如下是部分代码 for i=1,10 do self.startMartix[i]={} self.star[i]={} for j=1,10 do self.startMartix[i][j]= starSprite self.star[i][j]=star_