DeMarco
DeMarco

Reputation: 599

Ruby parallel sorting

I am trying to create a multithreaded version of a sorting algorithm. I do not understand why this algorithm always returns just Array[1] instead of the full array.

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

Upvotes: 1

Views: 281

Answers (2)

Mansueli
Mansueli

Reputation: 7004

From you examples it looks like you are trying to use Process where you actually want to use a thread.

Process: no shared resources with itś caller (Parent)

Thread: shares memory with its Parent

Your example would work if you replaced the Process.fork with 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

Upvotes: 1

sawa
sawa

Reputation: 168229

The local variables l and g are not passed beyond Process.fork. They are only valid within that block. For example,

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

In your code, the l and g assignments done before Process.fork are still valid when you call return l + [pivot] + g.

By the way, if you had intended l and g to be passed from Process.fork, then your initialization of these variables prior to Process.fork is meaningless.

Upvotes: 2

Related Questions