From: Nita Neou on 6 Jul 2010 11:57 Hi All I got a little problem when using thread function and variable, let's say this code : require 'rubygems' require 'watir' require 'thread' def testfunc(id) total = id + 5 puts "id #{id} is #{total}" end threads = [] numberlist = [1, 2, 3] for id in numberlist threads << Thread.new {testfunc(id)} end threads.each { |aThread| aThread.join } my output is : [sophoah(a)fedora ]$ ruby test.rb id 3 is 8 id 3 is 8 id 3 is 8 The fact is that I would like this output : id 1 is 6 id 2 is 7 id 3 is 8 I am suspecting that all variable id, and total are all share among all the thread, is that right ? why ? I thought variable in a block were not share among variable ? How can I fix this problem ? Thanks a lot for your help on it, Regards Nita
From: Roger Pack on 6 Jul 2010 12:15 > threads = [] > numberlist = [1, 2, 3] > for id in numberlist > threads << Thread.new {testfunc(id)} > end ... > The fact is that I would like this output : > id 1 is 6 > id 2 is 7 > id 3 is 8 what's happening is that "id" is being changed as it iterates through the numberlist. So when each thread starts and finally gets around to running "testfunc(id)" they all call it with the end value. The fix is that you can pass a value "through" to the new threads, thus: Thread.new(id) {|id| testfunc(id) } Then it will preserve the original value. -r -- Posted via http://www.ruby-forum.com/.
From: Jesús Gabriel y Galán on 6 Jul 2010 12:15 On Tue, Jul 6, 2010 at 6:00 PM, Nita Neou <sophoah(a)gmail.com> wrote: > Hi All > > I got a little problem when using thread function and variable, let's > say this code : > > require 'rubygems' > require 'watir' > require 'thread' > > def testfunc(id) > total = id + 5 > puts "id #{id} is #{total}" > end > > threads = [] > numberlist = [1, 2, 3] > for id in numberlist > threads << Thread.new {testfunc(id)} > end > > threads.each { |aThread| aThread.join } > > my output is : > [sophoah(a)fedora ]$ ruby test.rb > id 3 is 8 > id 3 is 8 > id 3 is 8 > > The fact is that I would like this output : > id 1 is 6 > id 2 is 7 > id 3 is 8 > > I am suspecting that all variable id, and total are all share among > all the thread, is that right ? why ? I thought variable in a block > were not share among variable ? How can I fix this problem ? Blocks in Ruby are closures, this means that inside the block you pass to Thread.new, the variable id is the same. The Thread class has a way to avoid this, take a look at the constructor: http://ruby-doc.org/core/classes/Thread.html#M000437 You can pass parameters to #new and it will pass them to the block. You can use this technique to use a variable in the block that is different for each thread, like this: def testfunc(id) total = id + 5 puts "id #{id} is #{total}" end threads = [] numberlist = [1, 2, 3] for id in numberlist threads << Thread.new(id) {|my_id| testfunc(my_id)} end threads.each { |aThread| aThread.join } $ ruby threads.rb id 1 is 6 id 2 is 7 id 3 is 8 Jesus.
From: Nita Neou on 7 Jul 2010 11:53 On Jul 7, 12:15 am, Jesús Gabriel y Galán <jgabrielyga...(a)gmail.com> wrote: > On Tue, Jul 6, 2010 at 6:00 PM, Nita Neou <soph...(a)gmail.com> wrote: > > Hi All > > > I got a little problem when using thread function and variable, let's > > say this code : > > > require 'rubygems' > > require 'watir' > > require 'thread' > > > def testfunc(id) > > total = id + 5 > > puts "id #{id} is #{total}" > > end > > > threads = [] > > numberlist = [1, 2, 3] > > for id in numberlist > > threads << Thread.new {testfunc(id)} > > end > > > threads.each { |aThread| aThread.join } > > > my output is : > > [sophoah(a)fedora ]$ ruby test.rb > > id 3 is 8 > > id 3 is 8 > > id 3 is 8 > > > The fact is that I would like this output : > > id 1 is 6 > > id 2 is 7 > > id 3 is 8 > > > I am suspecting that all variable id, and total are all share among > > all the thread, is that right ? why ? I thought variable in a block > > were not share among variable ? How can I fix this problem ? > > Blocks in Ruby are closures, this means that inside the block you pass > to Thread.new, the variable id is the same. > The Thread class has a way to avoid this, take a look at the constructor: > > http://ruby-doc.org/core/classes/Thread.html#M000437 > > You can pass parameters to #new and it will pass them to the block. > You can use this technique to use a variable in the block that is > different for each thread, like this: > > def testfunc(id) > total = id + 5 > puts "id #{id} is #{total}" > end > > threads = [] > numberlist = [1, 2, 3] > for id in numberlist > threads << Thread.new(id) {|my_id| testfunc(my_id)} > end > > threads.each { |aThread| aThread.join } > > $ ruby threads.rb > id 1 is 6 > id 2 is 7 > id 3 is 8 > > Jesus. Thanks both of you for your answer. Regards
|
Pages: 1 Prev: Shoes? Next: best way to make .rb into an executable for linux? |