【问题标题】:Is autoload thread-safe in Ruby 1.9?Ruby 1.9 中的自动加载线程安全吗?
【发布时间】:2011-02-19 17:49:19
【问题描述】:

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

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

提前感谢您提供任何见解。

【问题讨论】:

  • “这个著名的线程”链接已损坏

标签: ruby multithreading autoload ruby-1.9


【解决方案1】:

带来 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. 死锁...

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

【讨论】:

  • 我可以想象这种事情发生在一个线程服务器上,它的初始页面加载会触发大量的自动加载。上面两个线程实际上提到了这个场景。
  • 除此之外,值得注意的是,无论 ruby​​ 线程安全如何,event-machine isn't thread-safe。考虑到thin 和goliath 都是基于它的,而且mongrel 和webrick 都没有使用线程,而且mod_rack 依赖于mongrel/webrick 工作者,最终这并不重要。 ;-)
  • 深入挖掘。部分忽略我的最后评论。 Mongrel 实际上允许使用线程(但 Rails 在使用时并不是线程安全的)。而 mod_rack 实际上 公开 Rack 方法 - 它既不使用 mongrel/webrick,它使用在进程之间共享(一些)内存的 fork。
【解决方案2】:

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

autoloaded.rb:

sleep 1
Bar::Foo = 1

autoloader.rb:

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

t1 = Thread.new { Bar::Foo }
t2 = Thread.new { Bar::Foo }
t1.join; t2.join

【讨论】:

  • 哦。为什么哦为什么我没有想到这一点?在我自己复制它并尝试了一些压力测试变体之后(并用 RVM 确认它在 1.8.7、JRuby 和 Rubinius 中仍然存在问题——除了 1.9.1 和 1.9.2 的所有内容)我我打电话给这个回答。谢谢!
  • 我很惊讶它在 JRuby 中不是线程安全的——我认为线程安全是他们的目标之一。
【解决方案3】:

它总是坏掉。

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

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

class Lib
  extend SomeClassFuncs
  do_something_with_class_funcs
end

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

如果你看不到这个,你不应该线程。

【讨论】:

  • 上传?什么是分载? --我确实明白你的意思,但正如你所指出的,这种元编程与requireautoload 一样是线程不安全的。我的问题是,Charles Nutter 前段时间记录的 autoload 中的特定错误是否已在 Ruby 1.9 中得到修复,并且已经得到修复。
  • 无法修复自动加载线程安全漏洞。只有部分情况可以调整。
  • subload 是一个与自动加载功能竞争的库,并提供了类似于后来出现的 rails 急切加载工具的行为。它不再相关,但在当时有一些用途。
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 2016-05-05
  • 2012-07-08
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 2011-06-07
  • 2010-10-13
相关资源
最近更新 更多