什么时候需要将参数传递给`Thread.new`?

时间:2013-05-25 02:26:58

标签: ruby multithreading local-variables

在线程外部定义的局部变量似乎从内部可见,因此Thread.new的以下两种用法看起来是相同的:

a = :foo
Thread.new{puts a} # => :foo
Thread.new(a){|a| puts a} # => :foo

document给出了示例:

arr = []
a, b, c = 1, 2, 3
Thread.new(a,b,c){|d, e, f| arr << d << e << f}.join
arr #=> [1, 2, 3]

但是从a开始,bc从创建的帖子内部可见,这也应该与:

相同
arr = []
a, b, c = 1, 2, 3
Thread.new{d, e, f = a, b, c; arr << d << e << f}.join
arr #=> [1, 2, 3]

有什么区别吗?什么时候需要将局部变量作为参数传递给Thread.new

2 个答案:

答案 0 :(得分:18)

当你将一个变量传递给这样的线程时,该线程会生成一个变量的本地副本并使用它,因此对它的修改不会影响你传入的线程之外的变量

a = "foo"
Thread.new{ a = "new"}
p a # => "new"
Thread.new(a){|d| d = "old"} 
p a # => "new"
p d # => undefined

答案 1 :(得分:1)

我认为我遇到了实际问题。用这样的代码:

    sock = Socket.unix_server_socket(SOCK)
    sock.listen 10
    while conn = sock.accept do
        io, address = conn
        STDERR.puts "#{io.fileno}: Accepted connection from '#{address}'"
        Thread.new{ serve io }
    end

它在接受少量连接时似乎可以工作。当一个接一个地快速接受连接时,就会出现问题。除非将本地变量io作为参数传递给Thread.new

,否则对本地变量io的更新将反映在多个并发线程中。