Ruby线程使用不同的参数调用相同的函数

时间:2015-11-10 08:22:14

标签: ruby multithreading

我使用多个线程(例如10个线程)调用相同的Ruby函数。每个线程都将不同的参数传递给函数。

示例:

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号线中  创建线程号。五  创建线程号。 6  在第6号线中  在第6号线中  在第6号线中  在第6号线中  在第6号线中

当然我想得到输出:在线程号。 1(2,3,4,5,6)我能以某种方式实现这一点吗?

2 个答案:

答案 0 :(得分:3)

问题是for - 循环。在Ruby中,它重用了一个变量。 所以线程主体的所有块都访问同一个变量。循环结束时,此变量为6。线程本身可能仅在循环结束后才开始。

您可以使用each - 循环来解决此问题。它们更干净地实现,每个循环变量本身都存在。

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

不幸的是,ruby中的for循环是令人惊讶的来源。因此,最好始终使用each循环。

<强>增加: 您还可以给Thread.new一个或多个参数,并将这些参数传递到线程主体块中。通过这种方式,您可以确保块在其自身范围之外不使用vars,因此它也适用于for循环。

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

答案 1 :(得分: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 }