2015-11-10 1 views
4

Я вызываю одну и ту же функцию Ruby с количеством потоков (например, 10 потоков). Каждый поток передает разные аргументы функции.Рубиновые потоки, вызывающие одну и ту же функцию с разными аргументами

Пример:

def test thread_no 
    puts "In thread no." + thread_no.to_s 
end 

num_threads = 6 
threads=[] 

for thread_no in 1..num_threads 
    puts "Creating thread no. "+thread_no.to_s 
    threads << Thread.new{test(thread_no)} 
end 

threads.each { |thr| thr.join } 

Выход: Создание резьбы нет. 1 Создание потока №. 2 Создание резьбы №. 3 Создание резьбы №. 4 В резьбе № 4
Создание резьбы №. 5 Создание резьбы №. 6 не В нити No.6
В нить No.6
В нить No.6
В нить No.6
В нить No.6

Конечно, я хочу, чтобы получить результат: В потоке нет , 1 (2,3,4,5,6) Могу ли я как-то добиться того, что это сработает?

+0

представления о рубине, но то же решение, как всегда следует применять: используйте локальную переменную local_thread_no для thread_no при передаче ее в конструктор потока – Voo

ответ

3

Проблема for -loop. В Ruby он повторно использует одну переменную. Итак, все блоки тела нитей получают доступ к одной и той же переменной. Эта переменная равна 6 в конце цикла. Сам поток может запускаться только после завершения цикла.

Вы можете решить эту проблему, используя each -loops. Они более совершенны, каждая переменная цикла существует сама по себе.

(1..num_threads).each do | thread_no | 
    puts "Creating thread no. "+thread_no.to_s 
    threads << Thread.new{test(thread_no)} 
end 

К сожалению, for петли в рубине являются источником сюрпризов. Поэтому лучше всего использовать петли each.

Дополнение Вам также дают Thread.new один или несколько параметров, и эти параметры получить передается в блок нить тела. Таким образом, вы можете убедиться, что в блоке не используются никакие vars вне его собственной области, поэтому он также работает с for-loops.

threads << Thread.new(thread_no){|n| test(n) } 
0

@Meier уже упоминали причину for-end выплевывает другой результат, чем ожидалось.

for петля языка синтаксис конструкции, он повторно в той же локальной переменной thread_nothread_no и выходы 6, потому что ваш for цикл заканчивается до того, как последние несколько нити начинают выполняться.

Для того, чтобы избавиться от такого вопроса, вы можете сохранить копию точного thread_no в другой области - такие, как -

def test thread_no 
    puts "In thread no." + thread_no.to_s 
end 

num_threads = 6 
threads  = [] 

for thread_no in 1..num_threads 
    threads << -> (thread_no) { Thread.new { test(thread_no) } }. (thread_no) 
end 

threads.each { |thr| thr.join } 
Смежные вопросы