Является ли потокобезопасным для изменения различных ключей общего хэша между потоками? - PullRequest
2 голосов
/ 05 июля 2019

Безопасно ли для потоков разделять Ruby Hash между потоками и изменять его в каждом потоке, имея гарантию , каждый поток изменяет разные ключи (добавляет новый хеш с неопределенным, до выполнения, количеством ключей к нему)?

Я знаю, что это не безопасно для потоков, если потоки изменяют один и тот же ключ, однако я не уверен, безопасно ли, если они изменяют разные ключи.

например. ниже приведен пример программы, которая может проиллюстрировать проблему:

#!/usr/bin/env ruby
# frozen_string_literal: true

array = [*1..100]
hash = {}
array.each do |element|
    hash[element] = {}
end
threads = []
array.each do |element|
    threads << Thread.new do
        random = rand(1..100)
        hash_new_keys = [*0..random]
        hash[element] = {}
        hash_new_keys.each do |key|
            hash[element][key] = rand(1..10)
        end
    end
end
threads.each(&:join)

1 Ответ

3 голосов
/ 05 июля 2019

Если вы используете MRI, тогда его потокобезопасность позволяет изменять массив / хэш в разных потоках GIL гарантирует, что в данный момент активен только один поток.

Здесь есть 5 потоков, совместно использующих один объект Array. Каждый поток толкает ноль в массив 1000 раз:

array = []

5.times.map do
  Thread.new do
    1000.times do
      array << nil
    end
  end
end.each(&:join)

puts array.size


$ ruby pushing_nil.rb
5000

$ jruby pushing_nil.rb
4446

$ rbx pushing_nil.rb
3088

Поскольку MRI имеет GIL, даже если одновременно запущено 5 потоков, только один поток активен одновременно. Другими словами, вещи не действительно параллельно. JRuby и Rubinius не имеют GIL, поэтому, когда у вас есть 5 потоков работают, у вас действительно есть 5 потоков, работающих параллельно через доступные ядра.

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

Ссылка https://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...