rails控制器是multithreading的吗? 控制器中的Thread.exclusive

Rails控制器是multithreading的吗?

如果是这样,我是否可以通过简单地执行从多个线程运行来保护某段代码(每十分钟仅触发一次)

require 'thread' Thread.exclusive do # stuff here end 

我需要以某种方式在显示器上同步吗?

在基本的rails应用程序上运行rake middleware提供以下内容:

 use Rack::Lock use ActionController::Failsafe use ActionController::Reloader use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache use ActiveRecord::SessionStore, # use ActionController::RewindableInput use ActionController::ParamsParser use Rack::MethodOverride use Rack::Head run ActionController::Dispatcher.new 

机架堆栈上的第一项是Rack::Lock 。 这会锁定每个请求,因此一次只能处理一个请求。 因此, 标准 rails应用程序是单线程的。 但是,您可以在请求中生成新线程,这将使您的应用程序具有multithreading,大多数人从未遇到过这种情况。

如果你有问题……

 require 'thread' Thread.exclusive do # stuff here end 

…将确保块内的东西永远不会与任何其他代码并行运行。 在所有线程之间创建一个共享的Mutext (在类变量或其他东西中,但是这可以在开发模式下重新加载时擦除,所以要小心),并且如果你只是在Rack::Lock#call做的话就锁定它希望确保不会同时执行相同代码的两个实例。

此外,对于记录,每个请求在每个请求周期中创建和取消引用一个控制器。 没有两个请求应该看到相同的实例,尽管它们可能看到相同的类。

设置config.threadsafe! 几乎我所说的一切都是空的。 这将从堆栈中删除Rack::Lock ,这意味着您需要手动设置互斥锁以防止双重输入。 除非你有充分的理由,否则不要这样做。

即使没有Rack::Lock您仍然可以为每个请求获得一个控制器实例。 控制器的入口点确保通知对new process的调用。

我的理解是为控制器处理的每个HTTP请求创建一个新的控制器实例。

Ruby是单线程的。 因此,在任何时候,控制器一次只能处理一个请求。 如果有多个请求,则这些请求将排队等候。 为了避免这种情况,人们通常运行一小组Mongrels来获得良好的并发性。 它的工作原理如下(直接来自Mongrel WIKI FAQ ):

  1. 一个请求击中了杂种。
  2. Mongrel创建一个线程并解析HTTP请求标头
  3. 如果身体很小,那么它会将身体放入StringIO中
  4. 如果身体很大,那么它将身体流到临时文件
  5. 当请求被“煮熟”时,它会调用RailsHandler。
  6. RailsHandler查看文件是否可能是页面缓存的,如果是,则它会发送缓存页面。
  7. 现在您终于准备好处理Rails请求了。 锁!
  8. 仍然锁定,Mongrel调用Rails Dispatcher来处理请求,传入头文件,以及BodyIO或Tempfile for body。
  9. 当Rails完成后,解锁! 。 Rails(希望)将其所有输出都放入StringIO中。
  10. 然后Mongrel接受这个StringIO输出,任何输出头,并将它们快速地流回客户端。

    请注意,如果页面被缓存,则没有锁定。