Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Thành Thạo Ruby Fibers: Tăng Hiệu Suất & Song Song Với Kiểm Soát Tinh Vi

Nếu bạn muốn榨取最多性能出于你的Ruby项目,我们必须探索fibers和它们如何工作。

让我们从一个简单的问题开始…

纤维是什么?

纤维是工作者,它们运行代码并跟踪自己的进度。换句话说,纤维是并发机制。

是的!

就像线程。区别在于你对纤维的控制比线程多。

在什么意义上你有更多控制?

好吧。

你的操作系统决定何时运行线程 & 何时暂停它们。

纤维不是这种情况!

你必须准确告诉纤维何时运行 & 何时停止。

纤维 vs 线程

线程感觉像在后台运行,做它们的事。

纤维不这样做。

当纤维运行时,它成为主程序直到你停止它。

让我们看代码示例!

使用纤维:示例

用Fiber.new和block创建纤维。

示例:

f = Fiber.new { puts 1 }

然后用resume方法运行纤维。

像这样:

f.resume

这打印1并把控制权返回主程序。

但怎么停止纤维?

用Fiber.yield方法,这不同于用于block的yield关键字。

示例:

f = Fiber.new { puts 1; Fiber.yield; puts 2 }
f.resume # 1
f.resume # 2

这将在用resume启动纤维后打印1,然后停止。

如果你再次调用resume…

它将从离开的地方继续并打印2。

注意: 再次恢复此纤维导致FiberError: dead fiber called,因为没有更多代码可运行。

这就是为什么纤维有用!

在纤维内部调用Fiber.yield就像按暂停键。允许你在循环中间或你写在纤维block中的任何代码处停止。

纤维 & 循环:无限序列

我们可以用这个„暂停键“效果创建无限序列。

成分:

  • 纤维
  • 循环
  • 计数器

例如,阶乘数:

factorial = Fiber.new do
count = 1
loop do
Fiber.yield (1..count).inject(:*)
count += 1
end
end

你可以按需要多次用resume方法使用此纤维,获取序列中的下一个数字。

示例:

Array.new(5) { factorial.resume } # [1, 2, 6, 24, 120]

不错!

纤维 & IO:异步操作

纤维对必须等待的事情(如网络连接)比线程更快 & 更高效。

为什么?

因为纤维导致更少上下文切换。

上下文切换是CPU从当前任务变到另一个任务。

这有小成本,但累积起来!

我用Linux的perf工具做了一些测试,发现在简单Ruby应用中,纤维产生的上下文切换比线程少3倍。

听起来不错?

你现在就可以开始用纤维:

  • 用IO.select方法 + Reactor设计模式
  • 用async gem
  • 用falcon应用服务器

记住…

没有灵丹妙药,但值得测试 & 看纤维能为你做什么 🙂

总结

你已学会Ruby中的纤维!纤维允许你创建可按你意愿暂停 & 恢复的代码单元。

现在轮到你试试了。

谢谢阅读!