在Rails中线程化 - params []是否仍然存在?

时间:2010-10-08 08:46:12

标签: ruby-on-rails multithreading request response

我正在尝试在Rails中生成一个线程。我通常不习惯使用线程,因为我需要深入了解Rails的请求/响应周期,但我无法避免使用一个因为我的请求超时。

为了避免超时,我在请求中使用了一个线程。我的问题很简单。我使用的线程访问其中的params []变量。现在似乎工作正常。我想知道这是否正确?如果有人能够在请求/响应周期中使用线程中的线程,我会很高兴。

[开始赏金]

2 个答案:

答案 0 :(得分:5)

简短的回答是肯定的,但只是在一定程度上;创建线程的绑定将继续保持。只有当没有人(包括Rails)不顾一切地修改或删除params散列时,params仍然存在。相反,他们依靠垃圾收集器来清理这些对象。由于线程在创建时可以访问当前上下文(在Ruby中称为“绑定”),所以从该范围可以到达的所有变量(实际上是创建线程时的整个状态)都不能被垃圾删除集电极。但是,当在主线程中继续执行时,该主题线程中的变量值可以由主线程更改,甚至可以由您创建的线程更改,如果它可以访问它。这是线程的好处 - 也是垮台:它们与其他一切共享内存。

您可以使用以下函数模拟与Rails非常相似的环境来测试您的问题:http://gist.github.com/637719。如您所见,代码仍然打印5。

但是,这不是正确的方法。将数据传递给线程的更好方法是将其传递给Thread.new,如下所示:

# always dup objects when passing into a thread, else you really
# haven't done yourself any good-it would still be the same memory
Thread.new(params.dup) do |params|
  puts params[:foo]
end

这样,您可以确定对params的任何修改都不会影响您的线程。最佳做法是使用以这种方式传递给线程的数据,或者线程本身创建的内容。依赖线程外的程序状态是危险的。

正如您所看到的,有充分的理由不建议这样做。即使在Ruby中,多线程编程也是 hard ,而当你处理Rails中使用的库和依赖项时,尤其是。事实上,Ruby看起来似乎很容易,但它基本上是一个陷阱。你会遇到的错误是非常微妙的;它们将“随机”发生并且很难调试。这就是像Resque,Delayed Job和其他后台处理库这样的东西如此广泛使用并推荐用于Rails应用程序的原因,我建议使用它。

答案 1 :(得分:1)

问题是,当线程运行时,rails会保持请求打开,而不是保持值。

一旦请求结束,它就不会保留该值,除非确实需要,否则我也不建议保持请求保持打开状态。正如其他用户所说,在延迟工作中,某些事情会更好。

话虽如此,我们使用线程多次同时查询多个源并实际减少应用程序的响应时间(仅适用于管理员,因此不需要快速响应时间)并且如果内存正确服务如果你在最后调用join并等待每个线程完成,那么thread可以保持请求打开。