From: Robert Klemme Date: 2012-12-31T05:11:38+09:00 Subject: Re: Thread.start(variables) do question On Sun, Dec 30, 2012 at 2:09 PM, Matthew Kerwin wrote: > On 30 December 2012 22:43, Matthew Kerwin wrote: >> >> On 30 December 2012 21:21, Robert Klemme >> wrote: >>> >>> On Sun, Dec 30, 2012 at 2:38 AM, Grant Schoep >>> wrote: >>> Here's another way to demonstrate the effect: >>> >>> $ ruby -e 'for i in 0..4; Thread.new(i) {|n| sleep 1;p [i,n]} end;sleep >>> 2' >>> [4, 3] >>> [4, 4] >>> [4, 2] >>> [4, 1] >>> [4, 0] >> Or is there a potential race condition caused by possibly deferred >> execution of the block, which is avoided by performing the "renaming" >> assignment in the parent thread? I'm trying to think of an example, but am >> having trouble. > > Thought of one (sorry for replying to myself): > > a = 1 > loop do > Thread.new { b=a; p b } > a += 1 > end > > .. where `a += 1` is likely to run before `b=a`; as opposed to .. > > a = 1 > loop do > Thread.new(a) { |b| p b } > a += 1 > end > > .. where passing the value of _a_ to Thread#new is guaranteed to happen > before `a += 1`, so _b_ will always have the right value. This race condition is what my example posted earlier demonstrates. You can change it a bit to make it more similar to your a+=1 example: $ ruby -e 'a=0; 4.times {Thread.new(a) {|n| sleep 1;p [a,n]}; a+=1}; sleep 2' [4, 1] [4, 0] [4, 2] [4, 3] Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/