一:协同程序
1.什么是协同程序
Lua 协同程序与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。
协程和线程都是针对于函数来说的,一个函数的正常执行步骤是执行完此函数的所有代码再继续执行下面的代码:
但是协程可以让函数在某一步暂停,暂停也称为挂起,在挂起的地方先执行函数外的代码,然后在需要的时候让没有执行的代码再去执行。
2.定义协程
——coroutine coroutine.create(function fun)
返回值为一个协程(create后面必须跟上括号,括号不能放在下一行)
——function coroutine.wrap(function fun)
返回值为一个函数(方法)(create后面必须跟上括号,括号不能放在下一行)
3.开启协程
——coroutine.resume(coroutineName,[var arg.....])
——coroutineName([var arg.....])
使用coroutine.create和coroutine.wrap定义的区别:
使用create定义的协同程序在开启时需要使用coroutine.resume开启,而用wrap定义的协同程序在开启时只需要像调用函数一样开启:
4.暂停协程
coroutine.yield(returnValue1.,....,returnValueN)
使程序暂停在coroutine.yield()的地方:
5.继续协程
继续协程的函数与开启协程的函数一样:
第一次执行时必须传入需要的参数,继续执行可以不传入参数,直接开启协程即可
6.协同函数的返回值
6.1:协同函数执行完成后有返回值
——coroutine.resume的第一个返回值永远为是否开启协程成功,后面的值才是协同函数的返回值:
——coroutine.wrap的返回值就是协同函数的返回值:
6.2:协同函数暂停时有返回值
coroutine.yield的参数就是暂停时返回的参数,可以返回多个值:
——coroutine.resume的第一个返回值永远为是否开启协程成功,后面的值才是协同函数的返回值:
——coroutine.wrap的返回值就是协同函数的返回值:
7.查看协程的状态
string coroutine.status(coroutineName) 只能用于coroutine.create创建的协同函数,,返回一个状态的字符串。
在协同函数外面获取到的状态永远都不会是running只可能是dead或者suspended,因为当协程被挂起时或者执行完时才会执行协同函数外的代码。
想要取得正在运行的状态需要在协同函数内部获取:
一个协同函数的生命周期:
8.获取正在运行的线程号
string coroutine.running()
返回值为协同函数的线程号(内存地址)
与获取协程状态一样如果在协同函数外面获取则永远都是nil:
想要取得正在运行的协程需要在协同函数内部获取:
9.案例分析
——第一个
function foo (a)
print("foo 函数输出", a)
return coroutine.yield(2 * a)
end
co = coroutine.create(function (a , b)
print("第一次协同程序执行输出", a, b)
local r = foo(a + 1)
print("第二次协同程序执行输出", r)
local r, s = coroutine.yield(a + b, a - b)
print("第三次协同程序执行输出", r, s)
return b, "结束协同程序"
end)
print("main", coroutine.resume(co, 1, 10))
print("--分割线----")
print("main", coroutine.resume(co, "r"))
print("---分割线---")
print("main", coroutine.resume(co, "x", "y"))
print("---分割线---")
print("main", coroutine.resume(co, "x", "y"))
print("---分割线---")
——第二个
local newProductor
function productor()
local i = 0
while true do
i = i + 1
send(i) -- 将生产的物品发送给消费者
end
end
function consumer()
while true do
local i = receive() -- 从生产者那里得到物品
print(i)
end
end
function receive()
local status, value = coroutine.resume(newProductor)
return value
end
function send(x)
coroutine.yield(x) -- x表示需要发送的值,值返回以后,就挂起该协同程序
end
-- 启动程序
newProductor = coroutine.create(productor)
consumer()
|
请发表评论