lua手册中对协同程序进行讲解的时候大量穿插和多线程技术的对比。
但是我多线程还没有深入学习,所以不能从比较中得出协同程序较多线程的优点。
看了手册中协同程序的基础和过滤器,迭代和协同程序,初步给我的感觉如下:
协同程序的执行是有先后顺序的,多个协同程序嵌套执行是有明显的先后顺序的。
过滤器,单从代码上看,是对 coroutine.yield()传递回来的参数进行一定的加工然后传给另一个协同函数。
迭代器中的协同函数,把闭包进行了复杂化。
我们先看过滤器的过程代码如下:
function receive(prod)
local status,value = coroutine.resume(prod)
return value
end
function send(x)
coroutine.yield(x)
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 ()
local line = 1
while true 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
do
while true do
consumer(filter(producer()))
end
end
这段代码的目的,是从键盘读入一行数据,然后通过过滤器加工,最后发送给屏幕。
有两个协同函数在工作,
第一个,produces函数创建了一个协同程序,这个协同程序调用io.read函数读取信息,当coroutine.resume()唤醒协同程序的时候,协同程序开始工作,最后通过协同程序末尾调用的 coroutine.yield() 将读取到的数据传递出去。
第二个,filter函数也创建了一个协同程序,这个协同程序首先接受由第一个协同程序得到的结果,然后对结果进行加工,再通过和上一个协同程序同样的方式把数据传递出去。
理解这个问题的过程会比较难过,难点在于以下几点:
1、协同程序的工作方式,不是创建了它就会运行的,需要唤醒
2、协同程序的函数传递参数的方式,不需要显示的返回,一个协同程序能通过yield协同函数直接把参数返回到resume函数
3、yield函数会挂起协同程序。
4、把函数作为参数在各个函数之间调用,绕来绕去,容易晕。
5、匿名函数
但是如果深入的去理解这段demo,就会发现其实它们看起来是很明朗的,每个部分分工明确。
过滤器看起来更像是叫包装器。