On Aug 11, 2010, at 7:23 AM, Louis-Philippe wrote:

> Hi Scott,
> 
> If you haven't done so already, you might want to have a look at:
> http://www.macruby.org/documentation/gcd.html
> 
> it speaks of MacRuby integrating Apple's latest multi-threading strategy: 
> Grand Central Dispatch.

Grand Central Dispatch is a fine technology, and goes a long way toward making 
concurrency much easier to implement.  But concurrent  execution is only one 
form of multitasking and GCD is not a general solution to all multitasking 
problems. In this particular case we are talking about cooperatively scheduled 
coroutines which is multitasking, but not necessarily concurrency.

In Grand Central Dispatch, work is broken up in to a number of small units and 
those units are dispatched to queues.  Eventually a preemptive thread will come 
along and pick up that work, run it (possibly in parallel with other bits of 
work). When a thread runs some of the work, however, it runs that work all the 
way through. 

Contrast that with a Fiber.  Like a block, a fiber represents a unit of work 
you need to do, but it's work you can turn your attention to... spend some time 
on, and then put down again at predefined spots.  Later, when you are ready, 
you can pick up that work and continue at the same spot.  This is multitasking, 
but not concurrency.  Consider a simple example:

my_fiber = Fiber.new do
        number = 0
        loop do
                Fiber.yield number
                number = number + 1
        end
end

>> my_fiber.resume
=> 0

>> my_fiber.resume
=> 1

This is a coroutine. It has it's own execution context which is started with 
the first resume, runs up until the yield, and then suspends execution.  This 
is a simple example, but the coroutine could be calling other subroutines, or 
other complex tasks, with the yield suspending execution at any point along the 
way. At some point in the future, resume may be called again and execution 
continues where it left off up until the next time yield is called.

This type of multitasking would be hard to implement using GCD because GCD 
focuses on concurrency. Since each GCD block runs to completion, the solution 
would involve breaking up the Ruby code using the yield statements as 
boundaries and then dispatching those blocks to a queue. But that solution 
would quickly become untenable if you consider that the yield statements might 
come... say... in the middle of a case:while statement, or in the middle of a 
complex subroutine chain.

Another solution you might come up with is to submit the whole Fiber's block as 
a single GCD block and implement the yield as acquiring some multiprocessing 
lock (a semaphore or a condition lock for example).  If you do that, then 
you've got the added overhead of a concurrency lock for each yield and you've 
submitted a GCD block to a queue that contains an infinite loop.  That block is 
going to sit at the end of the queue, consuming one of the threads from the 
thread pool "forever".  If you get a bunch of these running at once... GCD is 
not going to be happy with your train cars sitting on his tracks.

Please don't get me wrong.  I __LOVE___ all the work that has gone into 
integrating GCD into MacRuby.  But I don't see how GCD is going to help someone 
implement the cooperative multitasking of Fibers, a Ruby 1.9 language feature.

Scott
_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to