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
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel