Ruby on rails Rails中的类实例变量应该在互斥对象中设置吗?
假设我在Rails项目中有一个Ruby类,它正在设置一个实例变量Ruby on rails Rails中的类实例变量应该在互斥对象中设置吗?,ruby-on-rails,ruby,ruby-on-rails-3,synchronization,Ruby On Rails,Ruby,Ruby On Rails 3,Synchronization,假设我在Rails项目中有一个Ruby类,它正在设置一个实例变量 class Something def self.objects @objects ||= begin # some logic that builds an array, which is ultimately stored in @objects end end end 是否可以多次设置@objects?在一个请求期间,当执行上述开始/结束之间的代码时,是否可能在第二个请求期间调用此方法?
class Something
def self.objects
@objects ||= begin
# some logic that builds an array, which is ultimately stored in @objects
end
end
end
是否可以多次设置@objects
?在一个请求期间,当执行上述开始
/结束
之间的代码时,是否可能在第二个请求期间调用此方法?我想这实际上是一个Rails服务器实例如何分叉的问题
我应该使用互斥锁
还是线程同步?e、 g:
class Something
def self.objects
return @objects if @objects
Thread.exclusive do
@objects ||= begin
# some logic that builds an array, which is ultimately stored in @objects
end
end
end
end
我要试试看
导轨是单螺纹的。对Rails应用程序的连续请求要么排队,要么由单独的应用程序实例(读:进程)处理。在Something
类中定义的类实例变量@objects
的值存在于流程的范围内,而不在应用程序的任何实例的范围内
因此,互斥锁是不必要的,因为您永远不会遇到两个进程访问同一资源的情况,因为这两个进程的内存空间是完全分开的
我认为这引发了另一个问题,@objects
是否打算成为共享资源,如果是这样的话,我认为它需要以不同的方式实现
免责声明:我可能在这里完全偏离了主题,事实上我有点希望这样我今天就能学到一些东西:)即使在MRI中,以多线程模式运行Rails也是可能的(也是可取的)。这可以通过更改production.rb
中的一行来实现
config.threadsafe!
在MRI中,两个线程不能同时运行代码,但上下文切换可以随时发生。在Rubinius和JRuby中,线程可以同时运行代码
让我们看看您显示的代码:
class Something
def self.objects
@objects ||= begin
# some logic that builds an array, which is ultimately stored in @objects
end
end
end
| |=
代码将扩展为如下内容:
class Something
def self.objects
@objects || (@objects = begin
# some logic that builds an array, which is ultimately stored in @objects
end)
end
end
这意味着该过程实际上有两个步骤:
@对象
@objects
为falsy,则将@objects
设置为开始/结束表达式的结果
class Something
MUTEX = Mutex.new
def self.objects
MUTEX.synchronize do
@objects ||= begin
# some logic that builds an array, which is ultimately stored in @objects
end
end
end
end
我要请叶胡达称体重……我也不确定,但我相当肯定你是对的。:)我真的觉得你离现场很近。我对你的回答有一个警告,那就是使用的是哪个口译员。例如,JRuby可能存在这些问题。因为它确实有真正的线程支持,所以每个进程不仅仅是父进程的分支。所以对于MRI,我想你说得对。我应该提到我的问题主要集中在MRI上。我的印象基本上与你在回答中概述的相同,但我认为这是值得核实的
@objects
不打算成为共享资源,而只是一个缓存,以防止重复查找耗时的进程。谢谢执行def self.objects是否更有效@objects | | MUTEX.synchronize{@objects | |=[…]};结束
-这样,如果已经设置了var,它就不会尝试获取锁了?另外,我们可以使用一个通用的线程.synchronize
块吗?