Correctness of a minimal parallel workers queue in Ruby
Like @Victor Moroz, I'm also a fan of Queue.  I also prefer to keep the threads around: it's a bit more efficient, but more important, the code is simpler:

require 'thread'

class ParallelWorkersQueue

  def initialize(slots)
    @work = Queue.new
    @threads = slots.times.map do
      Thread.new do
        while (work = @work.deq) != :stop
          work[]
        end
      end
    end
  end

  def join
    @threads.each do
      @work.enq(:stop)
    end
    @threads.each(&amp;:join)
  end

  def push(&amp;task)
    @work.enq(task)
  end

end


Example of its use:

pwq = ParallelWorkersQueue.new(2)
5.times do |i|
  pwq.push do
    puts i
  end
end
pwq.join

# =&gt; 0
# =&gt; 1
# =&gt; 2
# =&gt; 3
# =&gt; 4


Replace Queue with SizedQueue if you wish to limit the amount of work that can be awaiting a worker thread.