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