Thursday, February 08, 2007

Ruby Threads

Today, I encountered my first Ruby gripe.

Variables mapped from collection passed into Ruby threads are not independent of one another. If one thread changes the passed variable, all of other threads share the new variable.

Let's suppose I have an Array of items = ["item 1", "item 2", "item 3"]

Here's some code that takes each item in the array and does some processing on it, printing out "finished!" statements after each element is processed.

items.map{|item|
Thread.new(item){
#process with variable execution time goes here
puts "#{item} finished!"
}
}

Let's suppose the map task associated with "item 3" starts last and ends first. Then the output could look like this:

item 3 finished!
item 3 finished!
item 3 finished!

The explanation for this peculiar behavior is detailed in Ruby Central's Pragmatic Programmer's Guide:
"A thread shares all global, instance, and local variables that are in existence at the time the thread starts."