如何使用 Ruby 的 Fibers 实现并行任务?
How does one achieve parallel tasks with Ruby's Fibers?
我是纤程和 EventMachine 的新手,最近才发现纤程,当时我正在查看 Ruby 是否具有任何并发功能,例如 go-lang。
当您使用 Fiber 时,实际用例的示例似乎并不多。
我确实找到了这个: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 请求!耶!!!但是......我实际上如何异步使用它?该示例除了创建包含 Fiber 之外没有任何内容。
据我了解(和不了解):
async_fetch 在调用 f.resume 之前一直处于阻塞状态。
f为当前Fiber,即在EventMachine.run块中创建的wrapping Fiber。
async_fetch 将控制流返回给它的调用者?我不确定这是做什么的
为什么缠绕的光纤最后有resume?默认情况下光纤是否暂停?
在示例之外,我如何使用 fibers 说,发射一堆由键盘命令触发的请求?
例如:每次我输入一个字母时,我都会向 google 发出请求或类似的东西? - 通常这需要一个线程,主线程会告诉并行线程为每个请求启动一个线程。 :-\
我是并发/纤程的新手。但他们是如此有趣!
如果有人能回答这些问题,将不胜感激!!!
关于 Ruby 中的纤维存在 很多 的混淆。纤程不是实现并发的工具;它们只是一种组织代码的方式,可以更清楚地表示正在发生的事情。
在我看来,'fibers' 这个名字与 'threads' 很相似,这造成了混淆。
如果您想要真正的并发,即在所有可用的 CPU 上分配 CPU 负载,您有以下选项:
核磁共振Ruby
运行 多个 Ruby VM(即 OS 进程),使用 fork 等。即使在 Ruby 中有多个线程,GIL(全局解释器锁)防止 Ruby 运行时使用超过 1 个 CPU。
中日Ruby
与 MRI Ruby 不同,JRuby 在分配线程时会使用多个 CPU,因此您可以获得真正的并发处理。
如果您的代码大部分时间都在等待外部资源,那么您可能不需要这种真正的并发。 MRI 线程或某种事件处理循环可能适合您。
我是纤程和 EventMachine 的新手,最近才发现纤程,当时我正在查看 Ruby 是否具有任何并发功能,例如 go-lang。
当您使用 Fiber 时,实际用例的示例似乎并不多。
我确实找到了这个: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 请求!耶!!!但是......我实际上如何异步使用它?该示例除了创建包含 Fiber 之外没有任何内容。
据我了解(和不了解):
async_fetch 在调用 f.resume 之前一直处于阻塞状态。
f为当前Fiber,即在EventMachine.run块中创建的wrapping Fiber。
async_fetch 将控制流返回给它的调用者?我不确定这是做什么的
为什么缠绕的光纤最后有resume?默认情况下光纤是否暂停?
在示例之外,我如何使用 fibers 说,发射一堆由键盘命令触发的请求?
例如:每次我输入一个字母时,我都会向 google 发出请求或类似的东西? - 通常这需要一个线程,主线程会告诉并行线程为每个请求启动一个线程。 :-\
我是并发/纤程的新手。但他们是如此有趣!
如果有人能回答这些问题,将不胜感激!!!
关于 Ruby 中的纤维存在 很多 的混淆。纤程不是实现并发的工具;它们只是一种组织代码的方式,可以更清楚地表示正在发生的事情。
在我看来,'fibers' 这个名字与 'threads' 很相似,这造成了混淆。
如果您想要真正的并发,即在所有可用的 CPU 上分配 CPU 负载,您有以下选项:
核磁共振Ruby
运行 多个 Ruby VM(即 OS 进程),使用 fork 等。即使在 Ruby 中有多个线程,GIL(全局解释器锁)防止 Ruby 运行时使用超过 1 个 CPU。
中日Ruby
与 MRI Ruby 不同,JRuby 在分配线程时会使用多个 CPU,因此您可以获得真正的并发处理。
如果您的代码大部分时间都在等待外部资源,那么您可能不需要这种真正的并发。 MRI 线程或某种事件处理循环可能适合您。