如何使用Ruby的Fibers实现并行任务?

时间:2016-04-22 22:35:56

标签: ruby concurrency eventmachine fiber

我是光纤和EventMachine的新手,在我看到Ruby有任何并发​​功能时,最近才发现光纤,比如go-lang。

对于使用光纤的实际用例,似乎没有很多例子。

我确实找到了这个: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是当前的Fiber,它是在EventMachine.run块中创建的包装Fibre。

async_fetch会将控制流返回给其调用者吗?我不确定这是做什么的

为什么缠绕纤维最后会恢复?光纤是否默认暂停?

在示例之外,我如何使用光纤说出来,拍摄由键盘命令触发的一堆请求?

例如:每次我输入一封信,我都会向Google提出要求吗? - 通常这需要一个线程,主线程会告诉并行线程为每个请求启动一个线程。 : - \

我是并发/光纤的新手。但它们真是太有趣了!

如果有人能回答这些问题,那将非常感激!

1 个答案:

答案 0 :(得分:2)

在Ruby中有关于光纤的混淆很多。光纤不是实现并发的工具;它们只是一种组织代码的方式,可以更清楚地表示正在发生的事情。

名称'纤维'类似于'线程'在我看来,造成了混乱。

如果您想要真正的并发性,即在所有可用的CPU上分配CPU负载,您有以下选择:

在MRI Ruby中

运行多个Ruby VM(即OS进程),使用fork等。即使Ruby中有多个线程,GIL(全局解释器锁)也阻止Ruby运行时使用多个CPU。 / p>

在JRuby

与MRI Ruby不同,JRuby在分配线程时会使用多个CPU,因此您可以获得真正的并发处理。

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