Lua协同机制详解

来源:互联网 发布:博尔特的肌肉数据 编辑:程序博客网 时间:2024/04/29 07:28

今天再写点简单的控制线程挂起的操作,coroutine.yield()这个函数的使用,从协同的观点看:使用函数yield可以使程序挂起,当我们激活被挂起的程序时,将从函数yield的位置继续执行程序,直到再次遇到yield或程序结束。首先我们先看一段代码,如下:

             

co = coroutine.create(function ()
 for i=1,10 do
  print("co",i)
  coroutine.yield()
 end
end)

coroutine.resume(co)
print(coroutine.status(co))

这段代码比较简单,高手就不用来这里,呵呵,偶也是一个初学者,大家新手入门的话可以关注本博客,随时查看一下这些内容,coroutine.yield()其中这句话负责将正在运行的东西挂起,我们打印出它的状态可以看到如下结果,如图:

然后我们再继续添加一些代码,代码如下:

coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
print(coroutine.resume(co))

我们把已经结束的线程再继续的时候就出现以下情况,上面的代码只是为了展示给大家会出现什么结果,结果如下图:

我们可以看到最后打印出一个 :cannot resume dead coroutine(不能继续运行一个已经死亡的线程)。

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

然后我们再来看看协同这个东西的新鲜的东西,也许这个会是程序中最常用的,给该函数传递参数,下面我先贴下代码:

co = coroutine.create(function (a,b,c)
 print("co",a,b,c)
end)
coroutine.resume(co, 1, 2, 3)

大神们肯定又会说这么简单的代码我也会,有什么用呢?!这个不就表示,你在协同的时候还可以传入一些参数。然后我依旧给大家一个图来看结果:

接下来我们再看看协同的其他操作,还是先贴出代码来,作为一个码农,不看见代码,你们总会觉得不踏实,好了不废话了,看代码吧:

co2 = coroutine.create (function ()

    print("co", coroutine.yield())

end)

coroutine.resume(co2)

coroutine.resume(co2, 4, 5)

同样我们看看这个东西的运行结果,也就说你在继续线程的时候也可以传递参数进去,这就给了你最大的灵活性,虽然我们不可能把所有的特性在一个程序中都用上,好处自己慢慢体验吧,好了看结果吧:

前面写了一堆用匿名函数建立协同,也许你在处理的时候需要用自己定义的一个函数来作为传入参数建立协同,那么你可以参照以下代码:

function myfunction(b,c)
   a=b+c
   return a
end

co3 = coroutine.create (myfunction)
print(coroutine.resume(co3,4,5))

 

废话不多说了,直接给截图结果吧,一看大家谁都明白了。如图:

这里把协同的大概能用到的用法都讲了一遍,而且程序也都我自己调过了,大家只要模仿着做一次,这块的内容就差不多了。希望大家有什么问题可以提出来,我一定耐心解答,但是不要让我调程序。顺便补充一句(lua为非对称协同。)

最后给出所有的代码,方便懒人们复制黏贴:

 

co = coroutine.create(function ()
 for i=1,10 do
  print("co",i)
  coroutine.yield()
 end
end)

coroutine.resume(co)
print(coroutine.status(co))
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
print(coroutine.resume(co))

co1 = coroutine.create(function (a,b,c)
 print("co",a,b,c)
end)
coroutine.resume(co1, 1, 2, 3)

co2 = coroutine.create (function ()

    print("co", coroutine.yield())

end)

coroutine.resume(co2)

coroutine.resume(co2, 4, 5)

function myfunction(b,c)
 a=b+c
 return a
end

co3 = coroutine.create (myfunction)
print(coroutine.resume(co3,4,5))