我使用多个线程(例如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)我能以某种方式实现这一点吗?
答案 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_no
和thread_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 }