【问题标题】:Lua producer-consumer pattern with consumers waiting for different dataLua 生产者-消费者模式,消费者等待不同的数据
【发布时间】:2012-05-20 11:58:36
【问题描述】:

问题

  • 一个数据源生成{key, value}格式的数据
  • 多个接收器各自等待不同的密钥

示例

获取数据是循环运行的。有时我会想通过使用

来获得用键标记的下一个值
Value = MyClass:GetNextValue(Key)

我希望我的代码停在那里,直到值准备好(产生某种未来(?)值)。我尝试过使用简单的协程,但它们仅在等待任何数据时起作用。

所以我想问的问题是如何使用协程或类似概念(无线程)在 lua 中实现异步值?

旁注

主处理函数除了将值返回给等待的消费者外,还会自己处理一些传入的数据(例如,用特殊键标记)。

完整的使用上下文应该类似于:

-- in loop
    ReceiveData()
    ProcessSpecialData()
--

-- Called outside the loop:
V = RequestDataWithGivenKey(Key)

【问题讨论】:

    标签: asynchronous io lua producer-consumer


    【解决方案1】:

    如何实现异步值

    你首先不实现异步。你实现了异步函数:在被检索之前你不会取回值。

    首先,您的代码必须在 Lua 协程中。我假设您了解协程的护理和喂养。我将重点介绍如何实现RequestDataWithGivenKey

    function RequestDataWithGivenKey(key)
      local request = FunctionThatStartsAsyncGetting(key)
      if(not request:IsComplete()) then
        coroutine.yield()
      end
    
      --Request is complete. Return the value.
      return request:GetReturnedValue()
    end
    

    FunctionThatStartsAsyncGettingrequest 返回给函数。 request 是一个对象,它存储处理特定请求所需的所有数据。它代表要求价值。这应该是一个启动实际异步获取的 C 函数。

    request 将是一个用户数据或一个封装的 Lua 表,它存储足够的信息以与执行异步获取的 C 代码进行通信。 IsComplete 使用内部 request 数据来查看该请求是否已完成。 GetReturnedValue只能在IsComplete返回true时调用;它将值放在 Lua 堆栈中,以便该函数可以返回它。

    您的外部代码只需要在内部处理异步内容。在这些 Lua 协程的恢复之间,如果有未完成的请求,您将需要泵送正在执行获取的任何异步内容。

    【讨论】:

    • 感谢您的回答。但是,我想问一下,是否仍有可能像您所写的那样,将整个代码打包在协程中的 lua shell?我知道它可以用线程来完成,但我只是想知道是否有可能没有它们。
    • @Bartek:可能吗?这取决于很多你没有说的东西。异步访问的本质是什么?你如何访问它?等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多