开发手册 欢迎您!
软件开发者资料库

Lua - Coroutines

Lua Coroutines - 从简单和简单的步骤学习Lua编程语言,从基本到高级概念,包括概述,环境设置,基本语法,变量,数据类型,运算符,循环,决策,函数,字符串,数组,迭代器,表,模块,Metatables,协同程序,文件I / O,错误处理,调试,垃圾收集,面向对象,Web编程,数据库访问,游戏编程及其标准库。

简介

协程本质上是协作的,它允许两种或多种方法以受控方式执行.使用协同程序,在任何给定时间,只有一个协同程序运行,并且此运行协程仅在明确请求暂停时暂停其执行.

上述定义可能看起来模糊.我们假设我们有两种方法,一种是主程序方法,另一种是协程.当我们使用resume函数调用一个协同程序时,它会开始执行,当我们调用yield函数时,它会暂停执行.同样的协程可以继续执行另一个恢复函数调用,从它被暂停.这个过程可以持续到协程执行结束.

协同程序中可用的函数

下表列出了协同程序中所有可用的函数Lua及其相应的用法.

Sr .No.方法&目的
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函数的附加返回值.

示例

让我们看一个例子来理解协同程序的概念.

co = coroutine.create(function (value1,value2)   local tempvar3 = 10   print("coroutine section 1", value1, value2, tempvar3)   local tempvar1 = coroutine.yield(value1+1,value2+1)   tempvar3 = tempvar3 + value1   print("coroutine section 2",tempvar1 ,tempvar2, tempvar3)   local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)   tempvar3 = tempvar3 + value1   print("coroutine section 3",tempvar1,tempvar2, tempvar3)   return value2, "end"end)print("main", coroutine.resume(co, 3, 2))print("main", coroutine.resume(co, 12,14))print("main", coroutine.resume(co, 5, 6))print("main", coroutine.resume(co, 10, 20))

当我们运行上述程序时,我们将获得以下输出.

coroutine section 13210maintrue43coroutine section 212nil13maintrue51coroutine section 35616maintrue2endmainfalsecannot resume dead coroutine

上面的示例是做什么的?

如前所述,我们使用resume函数来启动操作和yield函数来停止操作.此外,您可以看到协程的恢复功能接收到多个返回值.

  • 首先,我们创建一个协同程序并将其分配给变量名称co,协程将两个变量作为参数.

  • 当我们调用第一个恢复函数时,值为3和2保留在临时变量value1和value2中直到协程结束.

  • 为了让您理解这一点,我们使用了tempvar3,最初为10由于在协程执行过程中value1保持为3,它会被协程的后续调用更新为13和16.

  • 第一个协同程序. yield返回两个值4和3到resume函数,我们通过更新yield语句中的输入参数3和2得到.它还接收协程执行的真/假状态.

  • 关于协同程序的另一个问题是如何处理下一个简历调用的句子,在上面例;你可以看到变量coroutine.yield接收下一个调用params,它提供了一种强大的方法来完成新操作并保留现有的param值.

  • 最后,一旦协程中的所有语句都被执行,后续调用将返回false并且"无法恢复死coroutine"语句作为响应.

另一个协程示例

让我们看看一个简单的协程,它在yield函数和resume函数的帮助下返回1到5之间的数字.如果不可用,它会创建协程,或者恢复现有的协程.

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   endendfor index = 1, 10 do   print(index, getNumber())end

当我们运行上述程序时,我们将获得以下输出.

112233445561728394105

通常会将协同程序与多道程序设计语言的线程进行比较,但我们需要了解协同程序具有类似的线程特性,但它们一次只执行一个并且永远不会同时执行.

我们控制程序执行顺序以满足临时保留某些信息的需要.使用带有协同程序的全局变量为协同程序提供了更大的灵活性.