On Sat, Jan 22, 2011 at 12:57 AM, Charles Oliver Nutter <head...@headius.com > wrote:
> I'm curious about this example in Queue#apply's rdoc: > > * gcdq = Dispatch::Queue.new('doc') > * @result = [] > * gcdq.apply(5) {|i| @result[i] = i*i } > * p @result #=> [0, 1, 4, 9, 16, 25] > > apply is said to issue the jobs in parallel, so this would be making > concurrent updates to the @result array. Are simple arrays in MacRuby > thread-safe? > Arrays in MacRuby are not inherently thread safe. However, "Dispatch::Queue.new" creates a serial queue. So, there is an error in that each invocation of the block will execute serially. If, instead, the example had used "Dispatch::Queue.concurrent", then there would be a potential bug, but the easiest way to work around that is: gcdq = Dispatch::Queue.concurrent @result = [] @result_q = Dispatch::Queue.new('@result_assignment_queue') gcdq.apply(5) { |i| res = i * i; @result_q.async { @result[i] = res } } p @result There's also a mixin available in the Dispatch gem which abstracts away the need for a serial queue for assignments by monkey-patching assignments to all happen on a serial queue. For those wondering about the advantages to this technique, it's worth noting that GCD has a much lower overhead than more traditional methods of parallelism. That said, if the calculation for each iteration is small, this is not a useful technique. However, if the calculation for each iteration is long or (more likely) non-deterministic -- as in waiting for an external call or a remote connection -- then this can be a useful technique to continue doing useful work while letting iteration complete in the background. Cheers, Josh
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel