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

SFE*_*ley 15 ruby multithreading autoload ruby-1.9

在我看来,自从这个着名的线程以来,Ruby社区一直在关注自动加载,因为出于线程安全原因而不鼓励使用它.

有谁知道这不再是Ruby 1.9.1或1.9.2中的问题吗?我已经看过一些关于包装需求的讨论等等,但1.9更改日志(或者至少和我能找到的一样多)似乎并没有解决这个特定的问题.我想知道我是否可以在没有任何合理悲伤的情况下合理地开始自动加载仅1.9的库.

提前感谢任何见解.

Den*_*rdy 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. 僵局...

结论可能是:如果您的应用程序中存在任何可能的死锁,则在启动线程之前需要您需要的所有内容.

  • 除此之外,值得注意的是,无论ruby线程安全如何,[事件机器都不是线程安全的](https://github.com/eventmachine/eventmachine/issues/97).考虑到瘦和巨人都是基于它,并且mongrel和webrick都不使用线程,并且mod_rack依赖于mongrel/webrick工作者,它在一天结束时并不重要.;-) (2认同)

小智 7

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

autoloaded.rb:

sleep 1
Bar::Foo = 1
Run Code Online (Sandbox Code Playgroud)

autoloader.rb:

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

t1 = Thread.new { Bar::Foo }
t2 = Thread.new { Bar::Foo }
t1.join; t2.join
Run Code Online (Sandbox Code Playgroud)

  • D'哦.为什么我为什么不这么想?在我自己复制并尝试一些压力测试变化之后(并且用RVM确认它在1.8.7中仍然被破坏,JRuby和Rubinius - 除了**1.9.1和1.9.2之外的一切**)我正在打电话这回答了.谢谢! (2认同)