Lua协程
Lua 协程
概述
协程具有协同的性质,它允许两个或多个方法以某种可控的方式协同工作。在任何一个时刻,都只有一个协程在运行,只有当正在运行的协程主动挂起时它的执行才会被挂起(暂停)。
上面的定义可能看上去比较模糊。接下来让我讲得很清楚一点,假设我们有两个方法,一个是主程序方法,另一个是一个协程。当我们使用 resume 函数调用一个协程时,协程才开始执行。当在协程调用 yield 函数时,协程挂起执行。再次调用 resume 函数时,协程再从上次挂起的地方继续执行。这个过程一直持续到协程执行结束为止。
协程中可用的函数
下面的表中列出 Lua 语言为支持协程而提供的所有函数以及它们的用法。
S.N. | 方法和功能 |
---|---|
1 | coroutine.create(f):用函数 f 创建一个协程,返回 thread 类型对象。 |
2 | coroutine.resume(co[,val1,...]): 传入参数(可选),重新执行协程 co。此函数返回执行状态,也可以返回其它值。 |
3 | coroutine.running():返回正在运行的协程,如果在主线程中调用此函数则返回 nil。 |
4 | coroutine.status(co):返回指定协程的状态,状态值允许为:正在运行(running),正常(normal),挂起(suspended),结束(dead)。 |
5 | coroutine.wrap(f):与前面 coroutine.create 一样,coroutine.wrap 函数也创建一个协程,与前者返回协程本身不同,后者返回一个函数。当调用该函数时,重新执行协程。 |
6 | coroutine.yield(...):挂起正在执行的协程。为此函数传入的参数值作为执行协程函数 resume 的额外返回值(默认会返回协程执行状态)。 |
示例
让我们通过下面的例子来理解一下协程这个概念。
1 | co = coroutine.create(function (value1,value2) |
coroutine section 1 3 2 10
main true 4 3
coroutine section 2 12 nil 13
main true 5 1
coroutine section 3 5 6 16
main true 2 end
main false cannot resume dead coroutine
1 |
|
function getNumber()
local function getNumberHelper()
co = coroutine.create(function ()
coroutine.yield(1)
coroutine.yield(2)
coroutine.yield(3)
coroutine.yield(4)
coroutine.yield(5)
end)
return co
end
if(numberHelper) then
status, number = coroutine.resume(numberHelper);
if coroutine.status(numberHelper) == “dead” then
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
end
return number
else
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
return number
end
end
for index = 1, 10 do
print(index, getNumber())
end
1 | 执行上述的程序,我们可以得到如下的输出结果: |
1 1
2 2
3 3
4 4
5 5
6 1
7 2
8 3
9 4
10 5
```
大家经常会把协程和多线程编程语言中的线程进行对比,但我们要明白,协程有着与线程类似的特性,但是协程与线程的区别在于协程不能并发,任意时刻只会有一个协程执行,而线程允许并发的存在。(译注:译者认为本质上协程其是就是线程,不过是用户态的线罢了,它将调度问题交由程序开发人员手动完成。)
我们通过控制程序执行顺序以满足获取某些临时信息的需求。配合全局变量的使用,协和会变得更加的灵活方便。