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@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
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
On Tue, Jul 6, 2010 at 6:00 PM, Nita N. [email protected] wrote:
total = id + 5
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.
On Jul 7, 12:15 am, Jesús Gabriel y Galán [email protected]
wrote:
def testfunc(id)
threads.each { |aThread| aThread.join }
id 3 is 8
numberlist = [1, 2, 3]
Jesus.
Thanks both of you for your answer.
Regards