Forks

class Forky
  def initialize(max=6) = ( @max, @cur, @que = max, [], [] )
  def add(prc=nil, &bl) = ( bl ? (@que << bl) : (@cur << fork {prc.call}) )
  
  def linger
    until @que.empty?
      add(@que.pop) while (@cur.size < @max && !@que.empty?)
      @cur.delete Process.wait if @cur.size == @max
    end
    
    Process.waitall
  end

end

forky = Forky.new

forky.add { 4.times {puts :slow; sleep 2} }
forky.add { 5.times {puts :apa; sleep 1} }
forky.add { 5.times {puts :gris; sleep 0.5} }
forky.add { 10.times {puts :hektor; sleep 0.2} }
forky.add { 10.times {puts :rabies; sleep 0.1} }

forky.linger # time 8 secs