Rails控制器是多线程的吗?控制器中的Thread.exclusive [英] Are rails controllers multithreaded? Thread.exclusive in controllers

查看:131
本文介绍了Rails控制器是多线程的吗?控制器中的Thread.exclusive的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rails控制器是否是多线程的?

Are Rails controllers multithreaded?

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

If so, can I protect a certain piece of code (which fires only once every ten minutes) from being run from multiple threads by simply doing

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

我需要以某种方式在监视器上进行同步吗?

on do I need to somehow synchronize on a monitor?

推荐答案

在基本的Rails应用程序上运行rake middleware会给出以下信息:

Running rake middleware on a basic rails app gives the following:

use Rack::Lock
use ActionController::Failsafe
use ActionController::Reloader
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActiveRecord::SessionStore, #<Proc:0x017fb394@(eval):8>
use ActionController::RewindableInput
use ActionController::ParamsParser
use Rack::MethodOverride
use Rack::Head
run ActionController::Dispatcher.new

机架堆栈上的第一项是 Rack::Lock .这将对每个请求进行锁定,因此一次仅处理一个请求.因此, standard rails应用程序是单线程的.但是,您可以在请求中生成新线程,这会使您的应用成为多线程,大多数人从未遇到过.

The first item on the rack stack is Rack::Lock. This puts a lock around each request, so only one request is handled at a time. As such a standard rails app is single threaded. You can however spawn new threads within a request that would make your app multi threaded, most people never encounter this.

如果您遇到问题...

If you are having issues…

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

…将确保块中的内容永远不会与任何其他代码并行运行.在所有线程之间创建一个共享的Mutext(在类变量之类的东西中,但是在dev模式下重新加载时可以擦除它,所以要小心),并且如果想要的话,最好像Rack::Lock#call那样对其进行锁定以确保不会同时执行同一代码的两个实例.

… would ensure that stuff inside the block is never run in parallel with any other code. Creating a shared Mutext between all threads (in a class variable or something, but this could be wiped when reloaded in dev mode, so be careful), and locking on it as Rack::Lock#call does is to be preferred if you just want to ensure no two instances of the same code is executed at the same time.

同样,为了记录起见,每个请求在每个请求周期中创建和取消引用一个控制器.尽管两个请求可能会看到相同的类,但它们都不应看到相同的实例.

Also, for the record, each request creates and dereferences one controller in each request cycle. No two requests should see the same instance, although they may see the same class.

设置config.threadsafe!几乎使我所说的一切无效.这会从堆栈中删除 Rack::Lock ,这意味着您需要设置一个手动互斥以防止再次进入.除非您有充分的理由,否则不要这样做.

Setting config.threadsafe! voids almost everything I said. That removes Rack::Lock from the stack, and means you will need to set a mutex manually to prevent double entry. Don't do it unless you have a really good reason.

即使没有 Rack::Lock ,您仍将为每个请求获得一个控制器实例.控制器的入口点可确保注意process中对new的调用.

Even without Rack::Lock you will still get one controller instance per request. The entry point to your controller ensures that, notice the call to new in process.

这篇关于Rails控制器是多线程的吗?控制器中的Thread.exclusive的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆