Lua协程
协程是非抢断式的多线程方式,看上去像多线程,其实如同名字说的—协程,在协调多段程序的运行并且各自的代码段是有自己独立的变量的cache。本文主要通过实例将协程的处理讲清楚。 接口函数:
coroutine.wrap有点特别,这个是我摘抄文档中的解释: 官方的一个实例:function foo (a)
print("foo",a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body",a,b)
local r = foo(a+1)
print("co-body",r)
local r,s = coroutine.yield(a+b,a-b)
print("co-body",r,s)
return b,"end"
end)
print("main",coroutine.resume(co,1,10))
print("main","r"))
print("main","x","y"))
print("main","y"))
输出结果:>lua -e "io.stdout:setvbuf 'no'" "test.lua"
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
调用顺序:看完这个例子之后,其实可以看出来这两个线程其实一直在配合做事情。当resume被调用的时候,主线程就暂停了活动,将运行的权限交给了coroutine来做事。当coroutine yield的时候,将会直接触发自己的coroutine暂停,激活主线程的resume的return,接着做事。所以理论上对一个coroutine的调用,函数中有几个yield,主线程的代码中需要些多少个resume函数,否则如果主线程只对coroutine做一次resume。但是这个也不会造成太多的内存问题,协程对象被释放掉之后也将不会存在内存泄露 function first_phase(a)
-- coroutine first phase
return coroutine.yield( a + 1 )
end
collectgarbage('collect')
print(string.format("after full garbage-collection cycle,memory: %d k",collectgarbage('count')))
for i = 1,100 do
local co = coroutine.create( function ( a,b )
local l_a,l_b = a,b
local m1 = first_phase(a)
-- coroutine second phase
local m2 = coroutine.yield( m1 + 1 )
-- coroutine third phase
return input * b
end)
first_return = coroutine.resume( co,10,8 )
-- without to call resume let coroutine to finish
if i == 99 then
collectgarbage('collect')
print(string.format("after full garbage-collection cycle,collectgarbage('count')))
end
end
collectgarbage('collect')
print(string.format("after full garbage-collection cycle,collectgarbage('count')))
输出: after full garbage-collection cycle,memory: 20 k
after full garbage-collection cycle,memory: 21 k
after full garbage-collection cycle,memory: 20 k
这个说明了问题,就是其实在coroutine的Up-value的数据都是被保存在coroutine对象中。一旦释放掉这些对象,其Up-value数据也将会被回收,即使是这个coroutine状态还是在suspended之下也没有关系。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |