Я пытаюсь создать многопоточную версию алгоритма сортировки. Я не понимаю, почему этот алгоритм всегда возвращает только Array[1] вместо полного массива.

class Array
  def quick_sort
    return self if self.length <= 1
    pivot = self[0]
    if block_given?
      less, greater_equals = self[1..-1].partition { yield(x, pivot) }
    else
      less, greater_equals = self[1..-1].partition { |x| x < pivot }
    end
    l = []
    g = []
    Process.fork {l = less.quick_sort }
    Process.fork {g = greater_equals.quick_sort}
    Process.waitall
    return l + [pivot] + g
  end
end
1
DeMarco 6 Мар 2015 в 11:24

2 ответа

Лучший ответ

Локальные переменные l и g не передаются за пределы Process.fork. Они действительны только в этом блоке. Например,

Process.fork{a = 2}
Process.wait
a #=> NameError: undefined local variable or method `a' for main:Object

В вашем коде назначения l и g, выполненные до Process.fork, по-прежнему действительны, когда вы вызываете return l + [pivot] + g.

Кстати, если вы намеревались передать l и g из Process.fork, то инициализация этих переменных до Process.fork бессмысленна.

2
sawa 6 Мар 2015 в 08:49

Из ваших примеров похоже, что вы пытаетесь использовать Process там, где вы действительно хотите использовать ветка.

Процесс: нет общих ресурсов с его вызывающим (родительским)

Тема: разделяет память со своим родительским

Ваш пример будет работать, если вы замените Process.fork на Threads:

l = []
g = []
left_thread = Thread.new {l = less.quick_sort }
right_thread = Thread.new {g = greater_equals.quick_sort}
left_thread.join
right_thread.join
return l. + [pivot] + g
1
Mansueli 6 Мар 2015 в 09:00