2013-06-18 2 views
2

Давайте этот код от этого вопроса:Что такое точка .join в Ruby threads?

Ruby multiple background threads

и добавьте строку:

require 'thread' 

def foo(&block) 
    bar(block) 
end 

def bar(block) 
    Thread.abort_on_exception=true 
    @main = Thread.new { block.call } 
end 


foo { 
sleep 2 
puts 'thread_1' 
}.join 

puts 'main_thread' 

Это выход я получаю:

thread_1 
main_thread 

Это может показаться логически многие, но это не для меня. я ожидал:

main_thread 
thread_1 

почему? Потому что так я вижу вещи

main_thread : ----------(starts thread_1)-(prints 'main_thread')--Done! 

thread_1 :       \-(sleeps 2 secs)----------(prints 'thread_1')--Done! 

Но этого не происходит. Если я удалю часть .join, то «thread_1» даже не появится. Из моего понимания .join зависает (приостанавливает основной поток). Зачем? Разве это не против параллелизма? Помогите уточнить мой разум?

ответ

2

Thread#join ждет завершения субтитров до продолжения, поэтому ожидаемый результат действительно то, что вы видите.

Если переместить присоединиться заявление в самом конце файла, а затем следовать ему:

puts 'main_thread joined!' 

Вы увидите:

main_thread 
thread_1 
main_thread joined! 
+0

Это хороший подход? Согласиться на эту позицию? Что делать, если мне придется отлаживать проект 10k строк, что произойдет, если мне придется отлаживать подобные ситуации? –

+0

Не уверен, что вы подразумеваете под «хорошим» подходом. Это зависит от того, что вы делаете. Re 10k line, будьте осторожны, что отладка многопоточных и связанных с параллелизмом проблем кода может быть очень сложной; убедитесь, что вы понимаете, что делаете перед погружением в потоки. –

0

Ruby Thread#join method делает блок вызывающий поток пока целевой поток не завершится, что позволит вам «контрольно-пропускной пункт» нескольких потоков.

Подумайте об этом таким образом, когда вы начинаете поток, вы переходите от одной строки исполнения к двум, и когда вы присоединяетесь к потоку, вы переходите от двух строк исполнения к одному.

Thread#start    Thread#join 
------+---->  ...  ------O---> 
     \---->  ...  ------/ 

Это может показаться странным, но это обычная ситуация. Например, предположим, что у вас есть поток, выполняющий работу в фоновом режиме, а другой поток не может действовать до тех пор, пока эта работа не будет выполнена; в этом случае «join» - это простой способ, чтобы потоки координировали свою деятельность.

Смежные вопросы