2

在过去的 12 个小时里,我一直在研究这个主题,但我似乎无处可去。我什至不知道这是否可能,但我希望这是因为它对继续我的项目大有帮助。

我正在尝试做的是创建协程,因此我使用的特定程序不会因为无法执行异步 http 请求而冻结。尽管我对协程的理解还停留在“嗯?它是如何工作的?”中,但我已经想出了如何去做那部分。阶段。我现在的问题是能够使用正确的信息响应多个请求。例如,以下应产生三个单独的响应:

foo(a)
foo(b)
foo(c)

wherefoo用里面的参数启动一个协程。如果全部单独请求,则返回正确的结果。但是,如果作为块请求,它只会返回foo(c)'s 结果。现在,我理解了这背后的原因,但我无法找到一种方法让它在作为一个块被请求时返回所有三个结果。为了帮助理解这个问题,这里是实际的代码:

function background_weather()
local loc = url.escape(querystring)
weatherpage = http.request("http://api.wunderground.com/api/004678614f27ceae/conditions/q/" .. loc .. ".json")
wresults = json.decode(weatherpage)
--process some stuff here, mainly datamining
end
--send datamined information as a response
coroutine.yield()
end

以及协程的创建:

function getweather ()
-- see if backgrounder running
  if background_task == nil or
   coroutine.status (background_task) == "dead" then
-- not running, create it
   background_task = coroutine.create (background_weather)
-- make timer to keep it going
 AddTimer ("tickler", 0, 0, 1, "",
           timer_flag.Enabled + timer_flag.Replace,
           "tickle_it")
  end  -- if
end -- function

querystring变量是使用初始请求设置的。我这里没有包含它,但是为了测试,12345作为querystring变量使用。计时器是脚本的原始作者初始化的东西,用于检查协程是否仍在运行,每秒戳一次背景直到完成。老实说,我什至不确定我是否正确地做到了这一点,尽管它似乎在程序中异步运行。

那么,是否可以在一个块中接收多个请求并正确返回多个响应?或者这对 Lua 来说是一项太多的任务吗?

4

2 回答 2

5

协程不是那样工作的。实际上,它们是阻塞的。

协程解决的问题是“我想要一个可以执行一段时间的函数,然后回去做其他事情,然后回来并保持与我离开时相同的状态”。

请注意,我没有说“我希望它在我做其他事情时继续运行”;代码流在协程上“停止”,只有在您返回时才会继续。

使用协程,您可以修改(并且在某些情况下促进)代码的行为方式,使其更加明显或易读。但它仍然是严格的单线程。

请记住,Lua 实现的内容必须由 C99 指定。由于这个标准没有线程实现,Lua 默认是严格的单线程的。如果你想要多线程,你需要将它连接到一个外部库。例如,luvit将 Luajit 与 libuv 库挂钩以实现此目的。

几个很好的参考:

于 2012-07-15T11:48:58.220 回答
1

Programming in Lua 的第 9.4 章包含一个很好的例子来说明如何处理这个确切的问题,使用协程和 LuaSocket 的 socket.select() 函数来防止忙循环。

不幸的是,我不相信有任何方法可以将 socket.http 函数与 socket.select 一起使用;PiL 示例中的代码通常是您所需要的,但它不能处理一些相当常见的情况,例如请求的 URL 发送重定向。

于 2012-07-15T20:34:08.920 回答