Ruby Fiber

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)很容易理解,通过比较能看出它们之间的区别。

 

SubroutineCoroutine

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 entryThe start of a coroutine is the first point of entry and subsequent points of entry are following yield commands.
Subroutines can return only oncecoroutines 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。


FiberThread
not concurrencyconcurrency
resume, suspend(call Fiber.yield或者等到block结束)resume, suspend
return and give control back to callernot 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的轻量级线程。

 

写道
Next to implementing control structures, Coroutines provide a way to use lightweight concurrency . In effect, they allow to implement userspace threads with cooperative scheduling. The Coroutines can either yield control to each other, or have centralized scheduling by handing off control to one scheduler Coroutine which then decides who gets scheduled next.

 

Ruby1.9实现了kernal threads(sometimes too heavy),所以提供一种轻量级的并行化方式是必要的。

 

写道
Nevertheless, creating a lot of kernel threads still has a lot of overhead, or might simply cause problems on OSes that have hard thread limits or struggle with large numbers of threads. It's in these cases, when a lightweight alternative is useful. It allows the code to be split among threads, if that is the logic, straightforward solution, but keeps the overhead down.

 

Fiber for JRuby

 

实现JRuby等其它ruby实现的Fiber会遇到一些困难:

 

写道
If Fibers get adopted in Ruby, this will create headaches for Ruby implementations targeting the JVM or CLR, such as JRuby, XRuby, Ruby.NET or IronRuby. None of them currently support Continuations because manipulating or reading the callstack is hard or impossible to do in these VMs . The lack of Continuations is a controversial issue, but doesn't seem to have caused problems with e.g. JRuby, because they are not widely used in Ruby. The only use of them in the Ruby 1.8 standard library is the Generator implementation, but, for instance, JRuby 1.0, solved this by implementing the same functionality without using Continuations.

 

即使用workarounds,也有一些值得担心的性能问题:

 

写道
While it's certainly possible to implement these features using workarounds, the question is whether these workaround will cause performance regressions. If, for instance, call stacks must be emulated on the heap, instead of using the VM's stack, this can lead to lower performance or prevent (JIT) compiler optimizations from being applied. Workarounds for asymmetric Coroutines would be easier to do, as they could make use of the VM's stack for method invocations.
 

 

用途

 

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----

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值