15

在我看来,自从这个著名的线程以来,Ruby 社区一直对自动加载感到有些害怕,出于线程安全的原因,不鼓励使用它。

有谁知道这在 Ruby 1.9.1 或 1.9.2 中是否不再是问题?我已经看到一些关于互斥锁等中包装要求的讨论,但是 1.9 更改日志(或至少我能找到的)似乎并没有解决这个特定问题。我想知道我是否可以合理地开始在仅限 1.9 的库中自动加载而不会感到任何悲伤。

提前感谢您的任何见解。

4

3 回答 3

9

带来 2011 年的更新,因为我也很好奇。

目前开放两张票:

核心开发人员建议在 CRuby/JRuby 1.9 中 require 和 autoload 以相同的方式工作并且是线程安全的。从某种意义上说,ruby 在文件完全加载之前一直保持锁定。

然而,这具有引入潜在死锁的不便副作用。具体来说:

  1. Th1 加载 A 并将其锁定
  2. Th2 加载 B 并将其锁定
  3. Th1 尝试加载 B 作为加载 A 的一部分,开始等待 Th2
  4. Th2 尝试加载 A 作为加载 B 的一部分,开始等待 Th1
  5. 僵局...

结论可能是:如果您的应用程序中存在任何死锁的可能性,则在启动线程之前需要您需要的一切。

于 2011-07-02T03:54:37.100 回答
7

我不知道一般情况,但该线程的复制示例在 1.9.1 中没有中断:

自动加载的.rb:

sleep 1
Bar::Foo = 1

自动加载器.rb:

module Bar
   autoload :Foo, 'autoloaded.rb'
end

t1 = Thread.new { Bar::Foo }
t2 = Thread.new { Bar::Foo }
t1.join; t2.join
于 2010-05-14T22:19:06.220 回答
-4

它总是坏掉。

subload 允许您在线程环境中切换模式。

我仍在线程环境中使用自动加载,但仅在单线程引导序列期间使用。我认为在现实世界的应用程序中拥有多线程启动过程没有任何充分的理由。如果您确实有一个,您可能需要排队加载共享库的操作,因为您总是会遇到类和实例级别设置的线程安全问题,主要是这样的事情:

class Lib
  extend SomeClassFuncs
  do_something_with_class_funcs
end

无论加载程序如何,此代码在加载时间都不是线程安全的。

如果你看不到这一点,你不应该穿线。

于 2010-06-14T11:02:48.847 回答