将param传递给ruby线程
鉴于这一点:将param传递给ruby线程,ruby,multithreading,Ruby,Multithreading,鉴于这一点: thr = [] for n in 0..6 do thr[n] = Thread.new { print n } end for n in 0..6 do thr[n].join end 我所期望的:0123456 我得到的:222000 目标是创建一个线程数组,并等待每个线程完成。显然,我对ruby线程的理解在这里是缺乏的 如何解决此问题?不要将n作为局部变量(具有词法范围)传递,而是作为块变量传递 以下代码将打印从0到6的数字各一次,尽管它
thr = []
for n in 0..6 do
thr[n] = Thread.new {
print n
}
end
for n in 0..6 do
thr[n].join
end
我所期望的:0123456
我得到的:
222000
目标是创建一个线程数组,并等待每个线程完成。显然,我对ruby线程的理解在这里是缺乏的
如何解决此问题?不要将
n
作为局部变量(具有词法范围)传递,而是作为块变量传递
以下代码将打印从0
到6
的数字各一次,尽管它们的顺序不保证
thr = []
for n in 0..6 do
thr[n] = Thread.new(n) {|n|
print n
}
end
for n in 0..6 do
thr[n].join
end
代码不起作用的原因是块中的n
引用了n
中定义的0..6中的n的n,该值在块的执行过程中发生变化。这并不是说你总是得到222000,而是在很多情况下,你会得到类似的结果。开始时的2
序列表明线程所需的时间。新建(n)
创建新线程并继续执行print n
大约等于for
循环执行两次迭代所需的时间。TL;博士
其他答案可能会说明代码不起作用的原因。相反,我将致力于如何获得你期望的结果
线程不按顺序执行。如果您希望从一系列线程中获得有序的输出,那么应该使用Ruby 2.3.0目前没有文档记录的
下面,我提供了同步和异步线程的示例,它们提供了您想要的有序输出。我还提供了一些关于线程安全性的注释
可能最简单的事情
虽然我在下面提供了更完整的示例,但在保留原始代码风格的同时,最简单的问题解决方案是:
for n in 0..6 do Thread.new { print n }.join end
通过在循环中使用#join,可以确保输出是有序的。这将正确地将以下内容打印到标准输出:
0123456
使用互斥体排序线程
下面是一个更惯用的示例,使用:
def有序_线程
结果=“”
(0..6)每个|
Mutex.new.synchronize{result“0123456”
实际上不需要使用,因为所有线程都是由互斥体顺序处理的
处理异步线程的输出
如果您不希望使用#synchronize带来额外的开销,那么您可以在之后对输出进行排序。例如:
def unordered_threads
result, threads = [], []
(0..6).each do |n|
threads << Thread.new { result << n.to_s }
end
threads.each &:join
result.sort.join
end
unordered_threads
#=> "0123456"
def无序_线程
结果,线程=[],[]
(0..6)每个|
线程您可以使用点击
创建变量n
的副本,因此在循环中对其进行修改不会影响已创建的线程
对象
thr = []
for n in 0..6 do
n.tap do |n|
thr[n] = Thread.new {
print n
}
end
end
for n in 0..6 do
thr[n].join
end
#=> 0123456
@boulder_ruby不会改变这个问题。我建议以不同的方式命名块变量,以避免混淆。
thr = []
for n in 0..6 do
n.tap do |n|
thr[n] = Thread.new {
print n
}
end
end
for n in 0..6 do
thr[n].join
end
#=> 0123456