Подтвердить что ты не робот

Thread.join блокирует основной поток

Вызов Thread.join блокирует текущий (основной) поток. Однако не вызывать результаты соединения во всех порожденных потоках, которые должны быть убиты при выходе основного потока. Как вы создаете постоянные дочерние потоки в Ruby, не блокируя основной поток?

Здесь типичное использование соединения.

for i in 1..100 do
  puts "Creating thread #{i}"
  t = Thread.new(i) do |j|
    sleep 1
    puts "Thread #{j} done"
  end
  t.join
end
puts "#{Thread.list.size} threads"

Это дает

     Creating thread 1  
     Thread 1 done  
     Creating thread 2  
     Thread 2 done  
     ...  
     1 threads  

но я ищу, как это сделать

    Creating thread 1  
    Creating thread 2  
    ...  
    101 threads  
    Thread 1 done  
    Thread 2 done  
    ...  

Код дает тот же результат как в Ruby 1.8.7, так и в 1.9.2

4b9b3361

Ответ 1

Вы просто накапливаете потоки в другом контейнере, а затем join их по очереди после того, как все они были созданы:

my_threads = []
for i in 1..100 do
    puts "Creating thread #{i}"
    my_threads << Thread.new(i) do |j|
        sleep 1
        puts "Thread #{j} done"
    end
end
puts "#{Thread.list.size} threads"

my_threads.each do |t|
    t.join
end

Вы также не можете привязать поток к переменной i, потому что i постоянно переписывается, а ваш вывод будет состоять из 100 строк "Thread 100 done"; вместо этого вы должны привязать его к копии i, которую я умело назвал j.

Ответ 2

Вам нужно присоединиться к потокам вне цикла.

for i in 1..100 do
  puts "Creating thread #{i}"
  t = Thread.new(i) do |mi|
    sleep 1
    puts "Thread #{mi} done"
  end
end

# Wait for all threads to end
Thread.list.each do |t|
  # Wait for the thread to finish if it isn't this thread (i.e. the main thread).
  t.join if t != Thread.current
 end