Thread.join блокирует основной поток - PullRequest
16 голосов
/ 14 августа 2010

Вызов 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

Ответы [ 2 ]

18 голосов
/ 14 августа 2010

Вы просто накапливаете потоки в другом контейнере, а затем 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.

7 голосов
/ 14 августа 2010

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...