在线程外部定义的局部变量似乎从内部可见,因此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
开始,b
,c
从创建的帖子内部可见,这也应该与:
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
?
答案 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的更新将反映在多个并发线程中。