Lua-基础(七)程序协同

发布于 2020-02-05  222 次阅读


使用协同程序可以更加高效的处理数据或执行任务

协同的基础

创建协同程序

image.png

local co=coroutine.create(function ()
    print('Hi')
end)

协程的状态

image.png
协同有三个状态:挂起态运行态停止态。当我们创建一个协同程序时他开始的状态为挂起态,也就是说我们创建协同程序的时候不会自动运行,可以使用 status 函数检查协同的状态:

print(coroutine.status(co))

启动协程

使用coroutine.resume()可以启动协程
image.png
例如:
coroutine.resume(co)
启动协程后,会立即执行协程方法中的内容。

挂起协程

如有需要coroutine.yield()可以挂起协程。
让我们来看下面这个例子,创建一个协程,在协程函数中构建一个循环,并在打印后挂起当前协程,我们不断的去调用协程。

local th=coroutine.create(function ()
    for i = 1, 3 do
        print("th=",i)
        coroutine.yield()
    end
end)
coroutine.resume(th)

coroutine.resume(th)
coroutine.resume(th)
coroutine.resume(th)
print(coroutine.resume(th)) -- 程序结束返回false

其运行结果如下图所示:
image.png
我们发现,在协程死亡时,coroutine.resume就返回false,并返回错误消息

Ps:resume 运行在保护模式下,因此如果协同内部存在错误 Lua 并不会抛出错误而是将错误返回给 resume 函数.

在resume和yield间交换数据

有没有办法在协程挂起时,返回一些数据呢?或在每次启动协程时,发送一些数据?
在lua中我们可以在resume和yield间交换数据。

传递参数:

-- 传递参数
local th2=coroutine.create(function (a,b,c)
    print("th2",a,b,c)
end)

coroutine.resume(th2,1,2,3)

当然我们也可以传递协程结果:

local th3=coroutine.create(function ()
    return 6,7
end)

print(coroutine.resume(th3))

Ps:
Lua提供的这种协同我们称为不对称的协同,就是说挂起一个正在执行的协同的函数与使一个被挂起的协同再次执行的函数是不同的,有些语言提供对称的协同,这种情况下,由执行到挂起之间状态转换的函数是相同的。

管道和过滤器

这个课题有点难,啃书中。。。
待更新