I don't think this is a bug. You should call Thread#join before you call Kernel.p.
Your thread may or may not not have been run by the time you call Kernel.p, and you may get
inconsistent results such as t[:var] being nil sometimes, and being "var" at other times.
Thanks a lot. You are totally right about Thread#join.
But what the solution in my particular case, how do I get thread-local variable when Thread.stop called within a thread.
t = Thread.new do
Thread.current[:var] = "var"
Thread.stop
end
t.join
p t[:var]
p t[:var]
yiedls
threads.rb:6:in join': deadlock detected (fatal) from threads.rb:6:in '
and it's supposed to be like that.
=begin
I also wanted to say this is rdoc's example of Thread#[] the one that tricked me.
Right now this is:
a = Thread.new { Thread.current["name"] = "A"; Thread.stop }
b = Thread.new { Thread.current[:name] = "B"; Thread.stop }
c = Thread.new { Thread.current["name"] = "C"; Thread.stop }
Thread.list.each {|x| puts "#{x.inspect}: #{x[:name]}" }
produces:
#<Thread:0x401b3b3c sleep>: C
#<Thread:0x401b3bc8 sleep>: B
#<Thread:0x401b3c68 sleep>: A
#<Thread:0x401bdf4c run>:
But on some slower machine it will produce different results.
Maybe it's better to change this example to something like following:
a = Thread.new { Thread.current["name"] = "A" }
b = Thread.new { Thread.current[:name] = "B" }
c = Thread.new { Thread.current["name"] = "C" }
Thread.list.each do |thr|
thr.join unless thr == Thread.main
puts "#{thr.inspect}: #{thr[:name]}"
end
produces:
#<Thread:0x88bf918 run>:
#<Thread:0x88b22cc dead>: A
#<Thread:0x88b2290 dead>: B
#<Thread:0x88b2254 dead>: C
Or some other more consistent example than current.
=end