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

bra*_*boy 3 multithreading ruby-on-rails response request

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

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

[开始赏金]

wup*_*tah 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
Run Code Online (Sandbox Code Playgroud)

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

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