2016-04-22 92 views
2

我是新来的光纤和EventMachine,并且最近才发现有关光纤,当我看到Ruby是否具有任何并发​​功能时,如go-lang。如何用Ruby的Fibers实现并行任务?

在使用光纤时,似乎并没有太多的实例用于实际用例。

我还是设法找到这个:https://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/(回从2009年!)

它具有以下代码:

require 'eventmachine' 
require 'em-http' 
require 'fiber' 

def async_fetch(url) 
    f = Fiber.current 
    http = EventMachine::HttpRequest.new(url).get :timeout => 10 
    http.callback { f.resume(http) } 
    http.errback { f.resume(http) } 

    return Fiber.yield 
end 

EventMachine.run do 
    Fiber.new{ 
    puts "Setting up HTTP request #1" 
    data = async_fetch('http://www.google.com/') 
    puts "Fetched page #1: #{data.response_header.status}" 

    EventMachine.stop 
    }.resume 
end 

这是伟大的,异步GET请求!好极了!!!但是......我如何实际使用它异步?该示例除了创建包含光纤外没有其他任何内容。

从我的理解(和不理解):

async_fetch阻塞,直到f.resume被调用。

f是当前光纤,它是在EventMachine.run块中创建的环绕光纤。

async_fetch将控制流转回给它的调用者?我不确定这是什么

为什么包装光纤在最后恢复?光纤是否默认暂停?

在这个例子之外,我该如何使用光纤来表达一些由键盘命令触发的请求?

喜欢,例如:每当我键入一个字母,我向谷歌或其他什么的请求? - 通常这需要一个线程,主线程会告诉并行线程为每个请求启动一个线程。 : - \

我是新来的并发/纤维。但他们非常耐人寻味!

如果有人可以回答这些问题,那将非常感谢!

回答

2

有一个很多在Ruby中的纤维混淆。纤维不是实现并发的工具;它们只是一种组织代码的方式,可以更清楚地表示发生了什么。

在我看来,'纤维'这个名字与'线索'相似,这有助于混淆。

如果你想真正的并发,也就是分布在整个CPU负载所有可用的CPU的,你有以下几种选择:

在MRI红宝石

运行多个Ruby VM的(即操作系统的进程) ,使用fork等。即使在Ruby中有多个线程,GIL(全局解释器锁)也可以防止Ruby运行时使用超过1个CPU。

JRuby中

与MRI红宝石,JRuby的将分配线程时使用多个CPU,这样你就可以得到真正的并发处理。

如果你的代码花费大部分时间等待外部资源,那么你可能不需要这种真正的并发。 MRI线程或某种事件处理循环可能适合您。

+0

这绝对是有用的信息!我想现在我只需要弄清楚我是否需​​要线程。我在项目中使用EventMachine,并使用用户键盘输入 - 在输入时,可能会发生一些请求。由于一切都已经完成,大部分时间应用程序都处于闲置状态,你是否说使用线程是不值得的?因为这个平衡会处理所有事情? – NullVoxPopuli

+0

作为一个侧面说明,在围绕ruby 3x3进行炒作之后(ruby 3.0比ruby 2.0快3倍),我不知道MRI Ruby是否会在未来使用多个CPU。 – NullVoxPopuli

+1

我曾经在RubyConf上向Matz问过这个问题。他说,不,使用多个CPU的MRI方法正在启动多个Ruby进程。 –

相关问题