Использование переменной экземпляра класса для мьютекса в Ruby
Замечания: Краткое описание кода показано нижене дистилляция кода, с которым у меня была проблема. Я оставил это оригинальное резюме здесь, так как кто-то еще уже ответил, нофактический код показан в ответе, который я предоставил ниже.
Мне не удалось выделить это в небольшом неудачном тестовом примере, но я получаю ошибку со следующей общей конструкцией:
class Foo
@mutex = Mutex.new
....
def self.bar
@mutex.synchronize { ... }
end
end
Если я создаю несколько потоков, вызывающихFoo.bar
иногда@mutex
будет оцениватьnil
вbar
, Если я использую константу (например, MUTEX) вместо переменной экземпляра, у меня нет этой проблемы.
Не знаю, значимо ли это, но я работаю на JRuby на многоядерной машине.
Буду признателен за любое объяснение или помощь в том, как изолировать проблему.
Обновление: я считаю, что это связано с автозагрузкой. С помощью Rails мне удалось воспроизвести похожую проблему со следующим содержимымfoo.rb
в одном из каталогов Rails автозагрузка из:
class Foo
@mutex = Mutex.new
def self.bar
@mutex.synchronize {}
end
end
Когда я тогда выполняю следующее в консоли Rails:
1.upto(4).map { Thread.new { Foo.bar }}.map(&:join)
Я получаю следующую ошибку:
RuntimeError: Circular dependency detected while autoloading constant Foo
from /Users/palfvin/.rvm/gems/jruby-1.7.10@javlats/gems/activesupport-4.0.1/lib/active_support/dependencies.rb:461:in `load_missing_constant'
from /Users/palfvin/.rvm/gems/jruby-1.7.10@javlats/gems/activesupport-4.0.1/lib/active_support/dependencies.rb:184:in `const_missing'
from (irb):1:in `evaluate'
и такое же поведение в CRuby (MRI Ruby).