我试图实现一个简单的超时类来处理不同请求的超时。
这是第一个版本:
class MyTimer
def handleTimeout mHash, k
while mHash[k] > 0 do
mHash[k] -=1
sleep 1
puts "#{k} : #{mHash[k]}"
end
end
end
MAX = 3
timeout = Hash.new
timeout[1] = 41
timeout[2] = 5
timeout[3] = 14
t1 = MyTimer.new
t2 = MyTimer.new
t3 = MyTimer.new
first = Thread.new do
t1.handleTimeout(timeout,1)
end
second = Thread.new do
t2.handleTimeout(timeout,2)
end
third = Thread.new do
t3.handleTimeout(timeout,3)
end
first.join
second.join
third.join
这似乎工作正常。所有的超时都是彼此独立的。萤幕撷取画面
但是,该代码的第二个版本会产生不同的结果:
class MyTimer
def handleTimeout mHash, k
while mHash[k] > 0 do
mHash[k] -=1
sleep 1
puts "#{k} : #{mHash[k]}"
end
end
end
MAX = 3
timeout = Hash.new
timers = Array.new(MAX+1)
threads = Array.new(MAX+1)
for i in 0..MAX do
timeout[i] = rand(40)
# To see timeout value
puts "#{i} : #{timeout[i]}"
end
sleep 1
for i in 0..MAX do
timers[i] = MyTimer.new
threads[i] = Thread.new do
timers[i].handleTimeout( timeout, i)
end
end
for i in 0..MAX do
threads[i].join
end
为什么会这样呢?
如何使用数组实现此功能?
有没有更好的方法来实现相同的功能?
在使用创建线程的循环中Thread.new
,该变量i
在main
线程(正在创建线程的地方)和所创建的线程之间共享。因此,i
seeby by的值handleTimeout
不一致,您将获得不同的结果。
您可以通过在方法中添加调试语句来验证这一点:
#...
def handleTimeout mHash, k
puts "Handle timeout called for #{mHash} and #{k}"
#...
end
#...
要解决此问题,您需要使用以下代码。在这里,参数被传递给Thread.new
块变量,然后使用块变量进行访问。
for i in 0..MAX do
timers[i] = MyTimer.new
threads[i] = Thread.new(timeout, i) do |a, b|
timers[i].handleTimeout(a, b)
end
end
您何时需要将参数传递给Thread.new
?中介绍了有关此问题的更多信息。还有这篇文章。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句