Является ли присваивание атомарной операцией в ruby MRI?

#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.