这是预期的
t = Thread.new{
Thread.current[:rabbit] = 'white'
}
##### t[:rabbit] = white
但是我不明白这一点:
class Whatever
def initialize
@thd = Thread.new{
Thread.current[:apple] = 'whatever'
}
end
def apple
@thd[:apple]
end
def thd
@thd
end
end
我想访问它们,为什么它们nil
?
Whatever.new.apple # nil
Whatever.new.thd[:apple] # nil
Whatever.new.thd.thread_variable_get(:apple) # nil
为什么会这样?如何访问@thd
线程变量?
答案 0 :(得分:4)
您在这里看到的是比赛条件。您正在尝试在运行线程主体之前读取线程变量 。
比较以下内容:
w = Whatever.new
w.apple
# => nil
w = Whatever.new
sleep 0.1
w.apple
# => "whatever"
无论线程主体是否及时Whatever.new.apple
运行都是随机的,对我来说似乎发生了0.1%的时间,但这在其他计算机上可能有所不同
1000.times.
map { Whatever.new.apple }.
each_with_object(Hash.new(0)) { |val, memo| memo[val] += 1 }
# => {nil=>999, "whatever"=>1}
2000.times.
map { Whatever.new.apple }.
each_with_object(Hash.new(0)) { |val, memo| memo[val] += 1 }
# => {nil=>1998, "whatever"=>2}
(注意:由于大量的线程产生会导致我的IRB耗尽资源,因此我无法尝试进行更多的迭代)
这与我所听到的被描述为“异步的第一规则”有关,也就是说,您无法从同步方法获得异步方法的返回值。处理此问题的常用方法是使用“回调”,Ruby可以使用yield
/块的形式来实现。
我建议寻找有关如何在Ruby中进行异步编程的教程。