Correctness of a minimal parallel workers queue in Ruby I've programmed a minimal parallel workers queue in Ruby, and I wanted to know if it's correct, and if there are simpler ways of implementing it.

I'm aware of the existence of MonitorMixin, but it won't save any code, I think.

The design is kept intentionally trivial (e.g. it uses Thread.abort_on_exception).

# Usage:
#
#   queue = ParallelWorkersQueue.new( &lt;threads&gt; )
#   queue.push { &lt;operation_1&gt; }
#   queue.push { &lt;operation_2&gt; }
#   queue.join
#
class ParallelWorkersQueue

  def initialize( slots )
    @max_slots  = slots
    @free_slots = slots

    @mutex              = Mutex.new
    @condition_variable = ConditionVariable.new

    Thread.abort_on_exception = true
  end

  def push( &amp;task )
    @mutex.synchronize do
      while @free_slots == 0
        @condition_variable.wait( @mutex )
      end

      @free_slots -= 1
    end

    Thread.new do
      yield

      @mutex.synchronize do
        @free_slots += 1

        @condition_variable.signal
      end
    end
  end

  def join
    @mutex.synchronize do
      while @free_slots &lt; @max_slots
        @condition_variable.wait( @mutex )
      end
    end
  end

end
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.