#ruby #concurrency #atomic #mri
#ruby #параллелизм #атомарное #mri
Вопрос:
Допустим, у меня есть эти два метода в моем классе.
def set_val(val)
@val = val
end
def get_val
@val
end
Я создам несколько потоков для вызова set_val
с разными значениями. Гарантируется ли, что чтение из @val
возвращает правильное значение, т. Е. не последнее присвоенное значение, а значение, которое было передано set_val
? Могу ли я получить что-то странное при чтении? Является ли операция присваивания атомарной? Является ли оно неделимым независимо от количества потоков?
Ответ №1:
Это немного зависит от используемой вами реализации Ruby. Что касается MRI Ruby (Ruby по умолчанию), это безопасная (атомарная) операция из-за ее глобальной блокировки интерпретатора, которая защищает некоторые операции, такие как назначения, от прерывания переключениями контекста.
JRuby также гарантирует потокобезопасность некоторых операций, включая присвоение переменным экземпляра.
В любом случае, пожалуйста, обязательно примите во внимание, что любой такой параллельный доступ может быть сериализован, казалось бы, случайным образом. То есть вы не можете гарантировать, какие потоки назначаются первыми, а какие последними, если вы не используете явные блокировки, такие как мьютекс.
Комментарии:
1. Не могли бы вы указать источник вашего ответа для MRI?
2. Ну, вся идея GIL заключается в том, чтобы гарантировать, что отдельные операции на уровне Ruby никогда не будут прерваны параллельным потоком. Даже такие вещи, как оператор = (который определенно небезопасен для использования в JRuby и других), безопасны в MRI.