Рубин: Хэш в памяти и потокобезопасный буфер? - PullRequest
1 голос
/ 14 апреля 2011

Я реализую своего рода буфер записи / хранения в библиотеке с поддержкой Redis, чтобы объединить несколько вызовов hincrby в один вызов.Буфер должен быть полностью атомарным и работать в нескольких потоках.

Я совершенно новичок в области безопасности потоков, поэтому;Существуют ли какие-либо существующие библиотеки или стандартизированные способы реализации глобального буфера / очереди на основе хэша, который прекрасно работает в многопоточных средах?

Например, хэш буфера будет работать примерно так: псевдокод:

buffer #=> { :ident1 => { :value_a => 1, :value_b => 4 },
       #     :ident2 => { :value_a => 2, :value_b => 3 } }

buffer[:ident1][:value_a] #=> 1

# saving merges and increments {:value_a => 2} into buffer[:ident1]
save(:ident1, {:value_a => 2})

buffer[:ident1][:value_a] #=> 3

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

1 Ответ

5 голосов
/ 14 апреля 2011

Как правило, вы предоставляете доступ к глобальному значению потокобезопасным способом, используя встроенный класс Mutex:

$buffer = {}
$bufflock = Mutex.new

threads = (0..2).map do |i|
  Thread.new do
    puts "Starting Thread #{i}"
    3.times do
      puts "Thread #{i} got: #{$buffer[:foo].inspect}"
      $bufflock.synchronize{ $buffer[:foo] = ($buffer[:foo] || 1) * (i+1) }
      sleep rand
    end
    puts "Ending Thread #{i}"
  end
end
threads.each{ |t| t.join } # Wait for all threads to complete

#=> Starting Thread 0
#=> Thread 0 got: nil
#=> Starting Thread 1
#=> Thread 1 got: 1
#=> Starting Thread 2
#=> Thread 2 got: 2
#=> Thread 1 got: 6
#=> Thread 1 got: 12
#=> Ending Thread 1
#=> Thread 0 got: 24
#=> Thread 2 got: 24
#=> Thread 0 got: 72
#=> Thread 2 got: 72
#=> Ending Thread 0
#=> Ending Thread 2

Код внутри блока Mutex#synchronize является атомарным на поток; один поток не может перейти в $bufflock, пока предыдущий поток не завершит работу с блоком.

См. Также: Одновременно хинный Pure-Ruby

...