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

(0)

相关推荐

  • Lua中的协同程序探究

    哎,周五晚上我都还这么努力看书,真是好孩子.(小若:不想吐槽了) 其实我都准备玩游戏看电影去的了,但是这书就摆在桌子上,而且正对着我,就想着,扫两眼吧. 结果一扫就不对劲了,因为这内容有点绕,有点小混乱,如果我现在不记录下来的话,下周一可能又要重新看一次了.   好吧,今天我们来聊聊协同程序. 1.什么是协同程序(coroutinue) 大家都知道线程吧?都知道多线程吧?协同程序就和这线程差不多,但是又有比较明显的区别. 多个协同程序在任意时刻只能执行一个,虽然线程在某种意义上也是这样,但这不是

  • Lua中的协同程序之resume-yield间的数据返回研究

    这次要介绍几个其实很简单,但是一定要小心的返回值规则. 1.resume的参数 resume函数除了第一个参数是协同程序外,还能继续传其他参数,如下代码: 复制代码 代码如下: local co = coroutine.create(function(name)         print(name);     end);     coroutine.resume(co, "resume param"); resume第二个参数为"resume parame",这个

  • 举例详解Lua中的协同程序编程

    协同程序是协同的性质,可以把两个或更多的方法以可控制的方式执行.随着协同程序,在任何给定的时间,只有其协同程序运行之一,这在运行协同程序只能暂停其执行时,明确要求暂停. 上述定义可能看起来模糊.来告诉它更清楚,假设我们有两个方法,一个主程序方法和协同程序.当我们使用恢复功能调用协程,其开始执行,当我们调用yield功能,暂停执行.再次同协程可以继续从它被暂停的另一个恢复功能调用执行.这个过程可以继续,直到执行了协程的结束. 协同程序可用的功能 下表列出了在Lua协同程序及其相应的使用所有的可用功

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

    协程是协同程序的简称,顾名思义,就是协同工作的程序.协程拥有自己独立的桟.局部变量和PC计数器,同时又与其他协同程序共享全局变量和其他大部分东西: 协程与线程的主要区别在于,一个多线程程序可以同时运行几个线程(并发执行.抢占),而协同程序却需要彼此协作地运行,即一个多协程程序在任意时刻只能运行一个协程,并且正在执行的协程只会在其显式地要求挂起(suspend)时,它的执行才会暂停(无抢占.无并发). Lua中所有与协程相关的函数都在coroutine(一个table)中: 函数create用于创

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

    这是一段分析 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的简介及优缺点

    什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西. 协同是非常强大的功能,但是用起来也很复杂. 线程和协同程序区别 协程是编译器级别的,线程是操作系统级别的,在多处理器情况下,多线程程序同时运行多个线程:而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起.这样Lua的协程就不能利用现在多核技术了.

  • Lua中的协同程序详解

    前言 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.从概念上讲,线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行.就是说,一个具有多个协同程序的程序在任意时刻只能运行一个协同程序,并且正在运行的协同程序只会在其显式地要求挂起时,它的执行才会暂停. 协同程序基础 Lua将所有关于协同程序的函数放置在一个名为"coroutine"的table中.函数c

  • Lua协程(coroutine)程序运行分析

    这是一段分析 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进阶教程之闭包函数、元表实例介绍

    复制代码 代码如下: function createCountdownTimer(second)    local ms=second * 1000;    local function countDown()       ms = ms - 1;    return ms;  end  return countDown; end timer1 = createCountdownTimer(1); for i=1,3 do    print(timer1()); end print("-----

  • Lua中的函数代码实例

    在lua中,函数是一种"第一类值",它们具有特定的词法域. 第一类值:表示在lua中,函数与其他传统类型的值(数字和字符串)具有相同的权利,函数可以存储到变量中(无论全局变量还是局部变量)或者是table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值. 词法域:是指一个函数可以嵌套在另一个函数中.内部的函数可以访问外部函数中的变量. 看例子代码: 复制代码 代码如下: do       function foo(a, b, c)          print(a, b, c

随机推荐