jstorimer
Joined 18 years ago
Karma
429
Submissions
56
Member since
Dec 6
Joined 18 years ago
Thanks for the comments about atomicity vs. thread-safety. Absolutely on point. The article started out demonstrating what happened with concurrent Array mutation, but then I put in that += operation and didn't address it. Sorry for not making the distinction. Atomicity is absolutely a different issue than a thread-safe collection. I'm publishing something new tomorrow that addresses this point.
To bring things back to code, the point I was originally trying to make is that this code is not thread-safe.
array = []
threads = []
10.times do
threads << Thread.new do
100.times { array.push(rand) }
end
end
threads.each(&:join)
# 10 threads each inserted 100 values, result should be 1000
puts array.size
Specifically, too many Ruby programmers won't think twice about this operation not being thread-safe: array.push(item)
But there's no such guarantee. This is demonstrated nicely when this code example is run on an implementation with no global lock, try it on JRuby. There are some very specific caveats that MRI makes for concurrent IO. If you have one thread that's waiting on IO (ie. waiting for a response from the DB or a web request), MRI will allow another thread to run in parallel.Given that MRI ships with a GIL, the only core classes that are intentionally aware of multi-threading concerns are Mutex, ConditionVariable, and Queue.