Якщо я правильно вас прочитав, ви хочете мати не більше 4 потоків обробки одночасно.
Мені здається, що ви повинні запускати лише 4 потоки, і всі вони повинні читати із спільної черги (частина стандартної бібліотеки потоків) для обробки елементів.
Потоки можуть закінчуватися, коли черга порожня.
Нарізання масиву на 4 рівні масиви та обробка кожного потоку 1/4 елементів передбачає, що кожен елемент обробляє одночасно. Якщо деякі займають більше часу, ніж інші, деякі з ваших ниток закінчаться рано.
Використовуючи чергу, жоден потік не зупиняється, поки спільна черга не порожня, тому, я думаю, це більш ефективне рішення.
Ось робоча програма на основі вашого коду для демонстрації:
require 'thread'
elements = [1,2,3,4,5,6,7,8,9,10]
def process(element)
puts "working on #{element}"
sleep rand * 10
end
queue = Queue.new
elements.each{|e| queue << e }
threads = []
4.times do
threads << Thread.new do
while (e = queue.pop(true) rescue nil)
process(e)
end
end
end
threads.each {|t| t.join }