访问存储在实例变量中的线程的线程变量
Accessing thread variables of threads stored in instance variables
这是意料之中的,
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
线程变量?
您在这里看到的是竞争条件。您试图在线程主体 运行 之前读取线程变量 。
比较以下:
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 运行 资源不足)
这与我听说的 "number one rule of async" 相关,即您无法从同步方法中获取异步方法的 return 值。通常的处理方法是使用 "callback",Ruby 可以用 yield
/ 块的形式来处理。
我建议在 Ruby 中查找有关如何进行异步编程的教程。
这是意料之中的,
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
线程变量?
您在这里看到的是竞争条件。您试图在线程主体 运行 之前读取线程变量 。
比较以下:
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 运行 资源不足)
这与我听说的 "number one rule of async" 相关,即您无法从同步方法中获取异步方法的 return 值。通常的处理方法是使用 "callback",Ruby 可以用 yield
/ 块的形式来处理。
我建议在 Ruby 中查找有关如何进行异步编程的教程。