I am writing an app that retrieves multiple web pages in one method
call. Threading has improved performance drastically for me, but I
need some help understanding how exactly the call to join is going to
affect my program.
%w{methodname1 methodname2 methodname3 methodname4}.each do |method|
threads << Thread.new(method) do |m|
r = eval("#{m}(string)") # each method call makes an HTTP
request
mutex.synchronize { result.merge!® }
end
end
threads.each { |t| t.join }
result
end
Seems like the call to join on each thread is necessary to keep the
script from getting ahead of itself, but if I exclude that line, it
doesn’t seem to hurt my results and the program runs a lot faster.
Also, sometimes I get deadlocked somehow if I do use the call to join
and I’m not certain as to why. Can someone help shed some light on the
situation? Do I need to call join? Any idea why I’m deadlocking?
Thanks!
Seems like the call to join on each thread is necessary to keep the
script from getting ahead of itself, but if I exclude that line, it
doesn’t seem to hurt my results and the program runs a lot faster.
Also, sometimes I get deadlocked somehow if I do use the call to join
and I’m not certain as to why. Can someone help shed some light on the
situation? Do I need to call join? Any idea why I’m deadlocking?
Thanks!
Thread#join simply says “Wait here until this thread has finished
executing”.
So what you’re doing is waiting for all threads to finish before
execution
continues, aka blocking main thread execution. Without the #join, the
values
in results will be nonderministic. Any perceived deadlocking is probably
whatever is in your eval call not timing out. You’ll have to watch out
carefully for that.
And exception handling, etc, will be ever so much clearer.
You can as well do
def method(string)
threads = %w{
methodname1
methodname2
methodname3
methodname4
}.map do |method|
Thread.new(method) do |m|
send(m, string) # each method call makes an HTTP request
end.map {|th| th.value}
end