协同程序,Lua的多个请求

时间:2012-07-15 09:41:07

标签: lua coroutine

在过去的12个小时里,我一直在研究这个问题,而我似乎无法随时随地。我甚至都不知道这是否可行,但我希望这是因为继续我的项目会有很长的路要走。

我试图做的是创建协同程序,因此我使用的特定程序不会因为无法执行异步http请求而冻结。我已经想出了如何做到这一点,尽管我对协同程序的理解仍然在“嗯?这是如何工作的?”相。我现在的问题是能够使用正确的信息响应多个请求。例如,以下内容应产生三个单独的响应:

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

其中foo使用里面的参数启动协同程序。如果全部单独请求,则返回正确的结果。但是,如果作为块请求,它将仅返回foo(c)的结果。现在,我理解这背后的原因,但是当我作为一个块请求时,我找不到让它返回所有三个结果的方法。为了帮助理解这个问题,这是实际的代码:

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来说是一个太重要的任务了?

2 个答案:

答案 0 :(得分:5)

协同程序不能那样工作。事实上,它们是封锁的。

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

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

使用协同程序,您可以修改(在某些情况下有助于)代码的行为方式,使其更明显或更清晰。但它仍然是严格的单线程。

请记住,Lua实现的必须由C99指定。由于此标准没有附带线程实现,因此默认情况下Lua严格是单线程的。如果您想要多线程,则需要将其挂钩到外部lib。例如,luvit将Luajit与libuv lib挂钩以实现此目的。

一些很好的参考资料:

答案 1 :(得分:1)

Lua编程的{p> Chapter 9.4包含一个很好的例子,说明如何处理这个确切的问题,使用协同程序和LuaSocket的socket.select()函数来防止busylooping。

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

相关问题