将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