Методы push / pop в YARV Arrays поточно-ориентированы?

Предположим, у меня есть пара (производитель, потребитель) потоков YARV (Tp,Tc) делиться Arrayq - Tp подталкивает к q, а также Tc всплывает от этого. Если порядок выполнения нажатий и выталкиваний не имеет значения, работает ли код без какого-либо механизма синхронизации?

1 ответ

Решение

Доступ к массивам является поточно-ориентированным в MRI/YARV (и только там) в большинстве случаев из-за его глобальной блокировки интерпретатора (GIL), таким образом, в основном случайно.

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

С учетом вышесказанного, Ruby поставляется с другим примитивом для связи между потоками, который, кстати, является единственным классом в MRI/VARV, который явно ориентирован на многопоточность: Queue. Он поддерживает подталкивание и извлечение объектов в поточно-ориентированном виде.

Возьмите этот пример из документации Ruby:

queue = Queue.new

producer = Thread.new do
  5.times do |i|
     sleep rand(i) # simulate expense
     queue << i
     puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
     value = queue.pop
     sleep rand(i/2) # simulate expense
     puts "consumed #{value}"
  end
end

Существует также хорошо поддерживаемый проект, называемый concurrent-ruby, который предлагает множество мощных примитивов для параллельного программирования между потоками.

Другие вопросы по тегам