Some help with threads

Hi, I am using threads to do some calculations and I would like some
help.

I have a function named “myfun(i,k)” which creates within its body some
arrays and does a bunch of stuff with them and returns an integer.

Then I create a second function named “seeder(k)” which does the
threading:

def seeder(k)
threads = []
result = []
for i in (1…k)
threads << Thread.new(i){
res << myfun(i, k)
}
end

threads.each {|t| t.join }
return result.min
end


I also posted the code here: http://pastebin.com/khM2qrgG

The above code does not give the correct results when I check it with
the serial version.

So how do I create an array as a local variable to function “seeder”
shared to the threads so that each thread puts its result to the array
and then I return the minimum of that array ?

I could not find an example of “Thread.current” and a shared array.

If it ain’t that easy maybe I could create a global array but I prefer
the local shared one.

PS: The local variables for each call of “myfun” within the threads
remain local to the call, right ?

You seem to have a typo ‘res’ vs ‘result’, but beyond that you cannot
know when each thread is going to append to ‘result’ so you need to
control access to ‘result’ (e.g. use a mutex) since Array is not
thread-safe for append.

-Tom

On Sun, Apr 25, 2010 at 5:42 PM, Nick N. [email protected] wrote:

return result.min
and then I return the minimum of that array ?
Posted via http://www.ruby-forum.com/.


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


blog: http://blog.enebo.com twitter: tom_enebo
mail: [email protected]


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Nick,

Not sure if this is part of your problem or if it occurred when you
created
your pastie, but you are referencing the variable ‘res’ within your
Thread
execution and the variable ‘result’ outside of the Thread execution.
Depending on how you are actually calling this, you may or may not be
catching an exception that is being thrown within the threads.

Also, I am not extremely familiar with Ruby (or JRuby for that matter)
threading, but I do not believe that Array methods (such as ‘<<’) are
thread-safe. Here is an alternative strategy that you could use:
def seeder(k)
threads = []
for i in (1…k)
threads << Thread.new(i){
Thread.current[‘result’] = myfun(i, k)
}
end

threads.each {|t| t.join }
results = threads.collect{|t| t['result']}
return results.min

end

This has the advantage of not sharing variables across multiple threads
and
avoiding most of the thread safety issues.

PS: The local variables for each call of “myfun” within the threads remain
local to the call, right?

If by local variables you mean variables defined in ‘myfun’, then yes.
However, keep in mind that if you were passing an object to ‘myfun’ that
was
initialized outside of the thread, each thread would reference the same
object. For example:
array = []
def myfun(param1, param2); param1<<param2; end
threads = (1…10).collect {|i| Thread.new {myfun(array, i)}}
threads.each {|t| t.join }
puts array.inspect
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

Thank you all for you answers and yes that was a typo in my paste :slight_smile:

I went with the threads.collect solution which is lean and clean.

I think that mutexes in general hurt the performance when it comes to
parallel terms that’s why I wanted to avoid them.

Thanks again.

On Apr 26, 2010, at 9:43 AM, Thomas E Enebo wrote:

You seem to have a typo ‘res’ vs ‘result’, but beyond that you cannot
know when each thread is going to append to ‘result’ so you need to
control access to ‘result’ (e.g. use a mutex) since Array is not
thread-safe for append.

-Tom

Also, consider the new JRuby::Synchronized feature:
http://www.ruby-forum.com/topic/206663

require ‘jruby/synchronized’

class SyncArray < Array
include JRuby::Synchronized
end

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email