Ruby 1.9 中的自动加载是线程安全的吗?

发布于 2024-09-01 18:59:13 字数 283 浏览 7 评论 0原文

在我看来,自从这个著名的帖子,出于线程安全原因不鼓励使用它。

有谁知道这在 Ruby 1.9.1 或 1.9.2 中是否不再是问题?我见过一些关于在互斥体等中包装 require 的讨论,但是 1.9 变更日志(或者至少是我能找到的那么多)似乎并没有解决这个特定的问题。我想知道我是否可以合理地开始在仅限 1.9 的库中自动加载,而不会产生任何合理的悲伤。

预先感谢您的任何见解。

It seems to me that the Ruby community has been freaking out a little about autoload since this famous thread, discouraging its use for thread safety reasons.

Does anyone know if this is no longer an issue in Ruby 1.9.1 or 1.9.2? I've seen a bit of talk about wrapping requires in mutexes and such, but the 1.9 changelogs (or at least as much as I've been able to find) don't seem to address this particular question. I'd like to know if I can reasonably start autoloading in 1.9-only libraries without any reasonable grief.

Thanks in advance for any insights.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦毁影碎の 2024-09-08 18:59:14

对此进行了 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. 死锁...

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

Bringing a 2011 update to this, since I was curious about it too.

Two tickets are currently opened:

The core devs suggest that require and autoload work in the same manner and are thread safe, in CRuby/JRuby 1.9. This, in the sense that ruby keeps a lock until the file is fully loaded.

This has the inconvenient side-effect of introducing potential deadlocks, however. Specifically:

  1. Th1 load A and locks it
  2. Th2 load B and locks it
  3. Th1 tries to load B as part of loading A, starts waiting for Th2
  4. Th2 tries to load A as part of loading B, starts waiting for Th1
  5. Deadlock...

The conclusion probably is: require everything you need before starting a thread if there's any potential for deadlock in your app.

薄凉少年不暖心 2024-09-08 18:59:14

我不知道一般情况,但该线程的重现示例在 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

I don't know about the general case, but repro example from that thread doesn't break in 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
原野 2024-09-08 18:59:14

它总是坏掉的。

子加载允许您在线程环境中切换模式。

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

class Lib
  extend SomeClassFuncs
  do_something_with_class_funcs
end

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

如果你看不到这一点,那么你就不应该进行线程化。

it's always broken.

subload allows you to switch modes when in a threaded environment.

I use autoload still in threaded environment, but only during a single threaded boot sequence. I don't see any good reason to have a multithreaded startup process in a real world application. If you do have one, you will likely need to queue up actions for loading shared libraries as you will always have thread safety issues with class and instance level setup, most partuclarly with things like:

class Lib
  extend SomeClassFuncs
  do_something_with_class_funcs
end

This code is not thread safe a load time, irrespective of the loader.

If you can't see this, you shouldn't be threading.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文