

A deep dive into Ruby Fibers
source link: https://blog.kiprosh.com/ruby-fibers/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


What are fibers?
Fibers are workers, they run code & keep track of their progress. They are a concurrency mechanism like threads but are contrasting in nature when compared with threads. The control flow of a thread can get interrupted at any time and another thread can take over. With fiber, the control only switches when we explicitly tell it to. In this article, we will dive deeper to understand this difference and how to implement Fibers.
First things first, the difference between #fibers and #threads
- Fibers are light-weight and they eat much less memory as compared to threads
- You have control over fibers than threads.
- Your operating system runs threads and decides when to run and pause but with fibers things are variant. We need to specify to a fiber when to start and when to stop.
- Fibers are means of writing code blocks which can be paused or resumed, much like threads, but the difference is it's scheduling is done by the programmer and not by the operating system.
- Threads run in the background doing their task, but when a fiber running, it becomes your main program until you stop it.
Fibers are light-weighted threads, i.e. they are high performant in comparision to threads and provide full control to the programmer on when to stop or start them. Let us look at the performance graph for fibers and threads and understand how they perform.

Two execution threads; one thread blocks for 40ms on an IO call and then takes 10ms to post-process the data; second thread needs 50ms of pure CPU time; vs same scenario implemented with Fibers and cooperative scheduling.
By default, Ruby MRI uses a fair scheduler, which means that each thread is given an equal time to run (10ms quantum) before it is suspended and the next thread is put in control. If one of your threads is inside a blocking call during those 10ms, think of it as time wasted - everyone is sleeping! By contrast, Fibers force the programmer to do explicit scheduling which can certainly add to the complexity of the program, but offer us the full flexibility of determining how our CPU resources are used and also help us avoid the need for locks in mutexes in our code! It can be seen that fibers are cheaper to create and perform better than threads.
How to implement fibers ?
When a fiber is created it doesn't run automatically. Rather, we need to explicitly ask it to run using the Fiber#resume
method.
example:
f = Fiber.new { puts 1 } f.resume => 1
It will keep in the running state and control your main program until you stop it.
But how to stop a fiber ?
We can stop a running fiber by calling Fiber.yield
method. ( It is separate from the yield
method which is used to return blocks)
Example:
f = Fiber.new { puts 1; Fiber.yield; puts 2 } f.resume => 1 f.resume => 2
The code that is running inside the fiber gives the control back to the caller by using Fiber.yield
.
After yielding or termination, the fiber
returns the last executed expression's value.
Example:
f = Fiber.new { puts 1; Fiber.yield; puts 2 } f.resume => 1 f.resume => 2 f.resume => FiberError (dead fiber called)
In the above example, when we run f.resume
it puts 1
to the screen and stops as it comes across the Fiber.yield
method but it resumes again from where it left of when we again call f.resume
and puts 2
on the console.
Calling the Fiber.yield
acts like a pause button in your program, when to pause when to resume and that is why fibers are to handy.
Creating loops and endless sequences using fibers
We can use fibers to create an infinite sequence using Fiber.yield
All we need are Fibers, Loop and a Counter.
Fiber.yield
can take arbitrary parameters or blocks to perform a specific task as well, let us take an example of creating a factorial
using a fiber.
factorial = Fiber.new do count = 1 loop do Fiber.yield (1..count).inject(:*) count += 1 end end
You can call the resume
method on this fiber factorial
and use it as many times as you want to get the next number in the sequence.
For example:
Array.new(4) { factorial.resume } => # [1, 2, 6, 24]
A fiber
allows you to write a code that can be paused & resumed at your own will and is highly performant as well.
This helpful SO answer states that
Fibers are something you will probably never use directly in application-level code. They are a flow-control primitive which you can use to build other abstractions, which you then use in higher-level code.
Try it out and let us know in the comments if you need any further help on this topic. Please share it with your peers and share your experiences, We would :heart: to hear from you.
For more information on Ruby Fibers, refer this link .
Thanks for reading!
Recommend
-
22
The official planned next C# release is C# 9. You can find in this
-
27
Table of Contents Terminology: Grid Lines Terminology: Grid Tracks Property: grid-template-columns Property: grid-template-rows Prope...
-
21
A majority of front-end developers deal with this buzzword all the time: V8. A big part of its popularity is due to the fact that it led JavaScript to a new level of performance. Yes, V8 is very fast. But, how do...
-
21
A Deep-Dive into Flink's Network Stack 05 Jun 2019 Nico Kruber Flink’s network stack is one of the core components that make up the flink-runtime module and sit at the heart of every Flink jo...
-
15
A Deep Dive into Rescalable State in Apache Flink 04 Jul 2017 by Stefan Richter (@StefanRRichter) Apache Flink 1.2.0, released in February 2017, introduced support f...
-
10
Ruby has various ways of performing iteration—loops, blocks and enumerators. Most Ruby programmers are at least familiar with loops and blocks but Enumerator and Fiber often stay in the dark. In this edition of Ruby...
-
10
Ruby Garbage Collection Deep Dive: Compaction May 2021 So far in this series, we’ve discussed
-
6
ruby3 Published on 22 June 2022 ...
-
7
Ruby has various ways of performing iteration—loops, blocks and enumerators. Most Ruby programmers are at least familiar with loops and blocks but Enumerator and Fiber often stay in the dark. In this edition of Ruby Magic...
-
5
A Deep Dive into Memory Leaks in RubyTony Rowan on Aug 10, 2022
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK