Ruby闭包,线程和范围

时间:2018-05-24 01:05:04

标签: ruby multithreading

我正在尝试编写一个线程化的Ruby应用程序,并且我在理解通过块传递给线程的变量的范围时遇到了一些麻烦。代码的简化版本在下面

def threadRoutine(p1,p2)
  puts "Thread #{Thread.current.object_id} started with parameters #{p1}, #{p2}"
  Kernel.sleep 5
  puts "Thread #{Thread.current.object_id} completed"
end

start = 0
threads = []
(1..10).each do 
  finish = start + 1
  threads << Thread.new{threadRoutine(start,finish)}
  puts "Started thread #{threads[-1].object_id} with parameters #{start},#{finish}"
  start = finish
end

threads.each do |t|
  t.join
end

此输出如下

Started thread 2002 with parameters 0,1
Thread 2002 started with parameters 0, 1
Started thread 2004 with parameters 1,2
Thread 2004 started with parameters 1, 2
Started thread 2006 with parameters 2,3
Thread 2006 started with parameters 3, 3
Started thread 2008 with parameters 3,4
Thread 2008 started with parameters 4, 4
Started thread 2010 with parameters 4,5
Thread 2010 started with parameters 5, 5

Thread 2010 completed
Thread 2004 completed
Thread 2002 completed
Thread 2006 completed
Thread 2008 completed

前两个线程成功启动,线程以与从外部例程传递的参数相同的参数开始。在此之后(线程2006及以后)线程中的p1参数接收“start”变量的值,该变量在调用Thread.new之后已更新

显然我误解了这里的工作方式,但我预计传递给Thread.new的块会创建一个闭包,其中包含调用块的变量值。这似乎并未持续发生。请注意,如果我按照调用Thread.new进行1秒睡眠,一切正常,但这感觉就像一个黑客,我想了解如何正确地做到这一点。

非常感谢任何解释和建议。

以下是我正在使用的Ruby版本的详细信息

jruby 9.1.4.0 (2.3.1) 2016-09-01 2e1327f Java HotSpot(TM) Client VM 25.51-b03 on 1.8.0_51-b16 +jit [mswin32-x86]

0 个答案:

没有答案