Bug #4480
closedThread-local variables issue: Thread#[] returns nil when called first time
Description
=begin
In ruby 1.9.2p180
t = Thread.new do
Thread.current[:var] = "var"
Thread.stop
end
p t[:var] #=> nil
p t[:var] #=> "var"
In ruby 1.8.7
p t[:var] #=> "var"
p t[:var] #=> "var"
=end
Files
Updated by robertgleeson (Robert Gleeson) over 13 years ago
=begin
Hi Andrei,
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,
Rob
=end
Updated by dre3k (Andrei Kulakov) over 13 years ago
=begin
Hi Robert,
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.
Apologies if it's a stupid question.
=end
Updated by dre3k (Andrei Kulakov) over 13 years ago
- File thread_rdoc_fix.patch thread_rdoc_fix.patch added
=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
Updated by naruse (Yui NARUSE) over 13 years ago
- Status changed from Open to Assigned
- Assignee set to nahi (Hiroshi Nakamura)
Updated by ko1 (Koichi Sasada) over 13 years ago
- ruby -v changed from ruby 1.9.2p180 (2011-02-18 revision 30909) [i686-linux] to -
(2011/06/26 18:24), Yui NARUSE wrote:
In ruby 1.9.2p180
t = Thread.new do
Thread.current[:var] = "var"
Thread.stop
endp t[:var] #=> nil
p t[:var] #=> "var"In ruby 1.8.7
p t[:var] #=> "var"
p t[:var] #=> "var"
It seems intentional. When the first access, the Thread.current[:var]
is not initialized (not reached the initialization code).
--
// SASADA Koichi at atdot dot net
Updated by nahi (Hiroshi Nakamura) over 13 years ago
On Sun, Jun 26, 2011 at 20:12, SASADA Koichi ko1@atdot.net wrote:
It seems intentional. Â When the first access, the Thread.current[:var]
is not initialized (not reached the initialization code).
You're right. I took this ticcket since it would be a RDoc issue.
Updated by nahi (Hiroshi Nakamura) over 13 years ago
- Category set to doc
- Target version changed from 1.9.2 to 1.9.3
Updated RDoc at r32260 based on Andrei's patch. I just wanted to remove Thread.main thing to concentrate Thread#[] behavior. Thanks!
Updated by nahi (Hiroshi Nakamura) over 13 years ago
- Status changed from Assigned to Closed