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

  

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值