2010-05-14 3 views
15

Мне кажется, что сообщество Ruby немного рассердилось на автозагрузку с this famous thread, что обескураживает его использование для обеспечения безопасности потоков.Является ли автозагрузка потокобезопасной в Ruby 1.9?

Кто-нибудь знает, если это уже не проблема в Ruby 1.9.1 или 1.9.2? Я видел немного разговоров об обертывании в мьютексах и т. Д., Но 1.9 changelogs (или, по крайней мере, столько, сколько я смог найти), похоже, не рассматривают этот конкретный вопрос. Я хотел бы знать, могу ли я разумно начать автозагрузку в 1,9-подобных библиотеках без какого-либо разумного горя.

Заранее благодарим за любые идеи.

+1

ссылка на этот «отказ знаменитый» –

ответ

7

Я не знаю, об общем случае, но репродукция пример из этого потока не ломается в 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 
+2

D'oh. Почему, почему я не подумал об этом? Выполнив его сам и попробовав некоторые варианты стресс-теста (и подтвердив с RVM, что он все еще сломан в 1.8.7, JRuby и Rubinius - все ** кроме ** 1.9.1 и 1.9.2), я звоню это ответили. Спасибо! – SFEley

+0

Я удивлен, что в JRuby он не является потокобезопасным - я думал, что безопасность потоков является одной из их целей. –

-4

он всегда сломан.

subload позволяет переключаться между режимами в поточной среде.

Я использую автозагрузку все еще в поточной среде, но только во время однопоточной последовательности загрузки. Я не вижу веских оснований для многопоточного процесса запуска в реальном мире. Если у вас есть, вы, вероятно, нужно будет стоять в очереди действий для загрузки общих библиотек, поскольку вы всегда будете иметь проблемы безопасности нить с классом и уровня экземпляра установки, наиболее partuclarly с такими вещами как:

class Lib 
    extend SomeClassFuncs 
    do_something_with_class_funcs 
end 

Этот код не является потокобезопасное время загрузки, независимо от загрузчика.

Если вы не видите этого, вы не должны нарезать резьбу.

+0

Subload? Что такое подзадача? - Я вижу вашу точку зрения, но, как вы указываете, такое метапрограммирование так же небезопасно, как «require», как с «autoload». Мой вопрос заключался в том, была ли исправлена ​​ошибка в автозагрузке, которая была задокументирована Чарльзом Нуттером некоторое время назад, в Ruby 1.9, и это было. – SFEley

+0

Subload - https://github.com/raggi/subload – raggi

+0

Ошибка безопасности автозагрузки не может быть исправлена. Только некоторые случаи могут быть скорректированы. – raggi

9

Принесите обновление 2011 года, так как мне тоже было любопытно.

Два билета в настоящее время открыты:

Основные разработчики предполагают, что требуется и автозагрузка работают таким же образом и поточно, в CRuby/JRuby 1.9 , Это в том смысле, что рубин сохраняет блокировку, пока файл не будет полностью загружен.

У этого есть неудобный побочный эффект введения потенциальных тупиков. В частности:

  1. Th1 нагрузки А и замки это
  2. Th2 нагрузки B и запирает его
  3. Th1 пытается загрузить B как часть нагрузки A, начинает ждет Th2
  4. Th2 пытается загрузить в часть загрузки B, начинает ждать Th1
  5. Тупик ...

Возможно, заключение состоит в том, что перед началом потока требуется все, что вам нужно, если в вашем приложении есть какой-либо потенциал для тупика.

+0

Будет ли желающим B, а B, желающим A, быть слабым запахом кода? –

+1

Я могу себе представить, как это происходит на многопоточном сервере, чья начальная страница загружает триггер автозагрузки. На вышеупомянутых двух потоках есть упоминание об этом самом сценарии. –

+2

Добавляя к этому, стоит отметить, что независимо от безопасности рубиновой нити [event-machine не является потокобезопасной] (https://github.com/eventmachine/eventmachine/issues/97). Учитывая, что и тонкие, и голиафы основаны на нем, и что ни из mongrel, ни webrick не используют нити, и что mod_rack полагается на mongrel/webrick, это не имеет большого значения в конце дня. ;-) –

Смежные вопросы