Ruby 1.9 带来了Fiber: http://www.infoq.com/news/2007/08/ruby-1-9-fibers
Ruby中的Fiber是一种semi-coroutine,第一次看到这个东西挺难理解。
Subroutine VS Coroutine
理解semi-coroutine之前先来了解下什么是coroutine,子程序(subroutine)很容易理解,通过比较能看出它们之间的区别。
Subroutine | Coroutine |
The lifespan of subroutines is dictated by last in, first out (the last subroutine called is the first to return) |
The lifespan of coroutines is dictated entirely by their use and need. |
The start of a subroutine is the only point of entry | The start of a coroutine is the first point of entry and subsequent points of entry are following yield commands. |
Subroutines can return only once | coroutines can return (yield) several times |
Practically, yielding returns the result to the calling coroutine and gives it back control, like a usual subroutine. However, the next time the coroutine is called, the execution does not start at the beginning of the coroutine but just after the yield call.
那什么是semi-coroutine:Semi-Coroutines are asymmetric Coroutines which are limited in their choice of transfer of control. Asymmetric Coroutines can only transfer control back to their caller, where Coroutines are free to transfer control to any other Coroutine, as long as they have a handle to it.
Fiber VS Thread
Ruby的Fiber是一种控制结构(后面会说到Fiber::Core),它的运行方式和操作方法很像thread。
Fiber | Thread |
not concurrency | concurrency |
resume, suspend(call Fiber.yield或者等到block结束) | resume, suspend |
return and give control back to caller | not return or give control back unless join it |
Fiber VS Closure
看下面这个方法:
fib = Fiber.new do f1 = f2 = 1 loop do Fiber.yield f1 (每次resume,在遇到Fiber.yield或者block结尾时结束) f1, f2 = f2, f1 + f2 (第二次resume,从这里开始) end end 10.times { puts fib.resume }
很容易想到用closure去实现它:
def local_proc f1 = f2 = 1 return Proc.new {f1, f2 = f2, f1 + f2; p f1;} end proc1 = local_proc 10.times {proc1.call}
上面两个方法的实现方式是很不相同的。Fiber方式通过 enable the automatic conversion of internal iterators, such as each, to enumerator or external iterators来实现。
Fiber::Core VS Fiber
相较于Fiber,Fiber::Core是真正的coroutine -- 一种可以实现userspace thread的轻量级线程。
Ruby1.9实现了kernal threads(sometimes too heavy),所以提供一种轻量级的并行化方式是必要的。
Fiber for JRuby
实现JRuby等其它ruby实现的Fiber会遇到一些困难:
即使用workarounds,也有一些值得担心的性能问题:
用途
Coroutines are well-suited for implementing more familiar program components such as cooperative tasks , iterators , infinite lists and pipes .。
References:
coroutine: http://en.wikipedia.org/wiki/Coroutine
用Ruby的fiber实现pipe的例子:http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html
----EOF----