Is Ruby Array # [] = threadsafe for a pre-distributed array? Can this make lawless?

I wrote code in ruby ​​to handle array elements through threadpool. In this process, I pre-allocated an array of results that is the same size as the passed array. In threadpool, I assign elements to a pre-allocated array, but the indices of these elements are guaranteed to be unique. With that in mind, do I need to surround the appointment with Mutex#synchronize?

Example:

SIZE = 1000000000
def collect_via_threadpool(items, pool_count = 10)
  processed_items = Array.new(items.count, nil)
  index = -1
  length = items.length
  mutex = Mutex.new
  items_mutex = Mutex.new
  [pool_count, length, 50].min.times.collect do
    Thread.start do
        while (i = mutex.synchronize{index = index + 1}) < length do


          processed_items[i] = yield(items[i])
          # ^ do I need to synchronize around this? `processed_items` is preallocated

        end
    end
  end.each(&:join)
  processed_items
end

items = collect_via_threadpool(SIZE.times.to_a, 100) do |item|
  item.to_s
end

raise unless items.size == SIZE

items.each_with_index do |item, index|
  raise unless item.to_i == index
end

puts 'success'

(This test code takes a lot of time, but each time it prints “success.”)

It seems I would like to surround Array#[]=with help Mutex#synchronizejust to be safe, but my question is:

Does the Ruby specification specify this code as safe?

+4
1

Ruby , Mutex (, , ). , , , .

MRI Array.new(n, nil) , , , . , , .

Array.new(n, nil) , , .

, ( , ), . , Ruby . , , , , , .

+1

All Articles