[MacRuby-devel] Thread safety in apply example?

Alan Skipp al_skipp at fastmail.fm
Mon Jan 24 08:00:41 PST 2011


The post was admittedly vague, but was more of an idea about a general purpose thread safe array class (in principle, this could apply to any mutable class). Perhaps implemented as a module that would redirect all method calls through a serial dispatch queue. This would mean that the array (or other mutable collection) could be mutated from multiple threads/queues without fear of bad things happening.

On 24 Jan 2011, at 15:22, Matt Massicotte wrote:

> What's the advantage of this over just iterating over the array serially using each?
> 
> Matt
> 
> On Jan 24, 2011, at 3:40 AM, Alan Skipp wrote:
> 
>> Warning, horrible hack alert!
>> I'm sure there must be a far better implementation, but the idea is to have an array subclass which diverts all method calls through a serial dispatch queue, which should ensure thread safe access.
>> 
>> Anyway, here's the horrible hack. By the way, it manages to break Enumerable, other than that it's perfect!
>> 
>> class ThreadSafeArray < Array  
>> instance_methods.each do |meth|
>>   eval "
>>   def #{meth}(*args, &block)
>>     val = []
>>     @serial_queue.async(@group) do      
>>       val[0] = super
>>     end
>>     @group.wait
>>     val[0]
>>   end"
>> end
>> 
>> def initialize(size=0, obj=nil)
>>   @serial_queue = Dispatch::Queue.new("array.serial_queue")
>>   @group = Dispatch::Group.new
>>   super
>> end
>> end
>> 
>> gcdq = Dispatch::Queue.new('doc')
>> @result = ThreadSafeArray.new
>> gcdq.apply(5) {|i| @result[i] = i*i }
>> p @result  #=> [0, 1, 4, 9, 16, 25]
>> 
>> 
>> Having to create an array for every method call to copy the return value into is terrible, is there a better way of getting a reference to the return value from a dispatch queue?
>> 
>> 
>> 
>> On 22 Jan 2011, at 14:52, Ernest N. Prabhakar, Ph.D. wrote:
>> 
>>> Hi Charles,
>>> 
>>> On Jan 21, 2011, at 9:57 PM, Charles Oliver Nutter 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?
>>> 
>>> My assumption was that doing a parallel assign:
>>> 
>>> result[i] = i*i
>>> 	
>>> would be safe, since it always accessed a unique portion of memory, but doing a serial append:
>>> 
>>> result << i*i
>>> 
>>> would not.  But that may have been a mistake on my part, since the size (at least) needs to be updated. Anyone know better?
>>> 
>>> -- Ernie P.
>>> 
>>> 
>>>> 
>>>> - Charlie
>>>> _______________________________________________
>>>> MacRuby-devel mailing list
>>>> MacRuby-devel at lists.macosforge.org
>>>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>>> 
>>> _______________________________________________
>>> MacRuby-devel mailing list
>>> MacRuby-devel at lists.macosforge.org
>>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>> 
>> _______________________________________________
>> MacRuby-devel mailing list
>> MacRuby-devel at lists.macosforge.org
>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel



More information about the MacRuby-devel mailing list