Fiber isjust a thread implemented in user space.
Fibers are easier to reason about than threads. And have much cheaper context switching cost. Fibers are well suited for handling concurrent IO operations where a processor mostly wait for data, and threads usually have pretty big context switching cost. So multiple fibers running in a single thread is an effective solution.
Here is a simple program I wrote to explore fibers. You can find the full example below.
playground/fiber.cpp at a5fba9f21ff121249c71bff75ee8964c1016aa3f · dilawar/playground
This program has two functions:print_a
printsa
andprint_b
printsb
and then launches a thread that printsB
(in detached mode).
voidprint_a(){cout<<"a";boost::this_fiber::yield();}voidprint_b(){cout<<"b";std::threadj([](){printf("B");});j.detach();boost::this_fiber::yield();}
Following is themain function. We created a shared variablei
initialized to 0. We create twodetach
ed fibers. The first one keeps callingprint_a
tilli < 20
. Similarly, the second one loops onprint_b
tilli < 20
. Both incrementi
by 1. Wheni = 20
, both fibers should be able tojoin
.
intmain(){inti=0;boost::fibers::fiber([&](){do{print_a();i++;}while(i<20);}).detach();boost::fibers::fiber([&](){do{i++;print_b();}while(i<20);}).detach();printf("X");return0;}
Let’s guess the output of this program. It is most likely to be the same as ifstd::thread
s were used instead of fiber.
X
is printed first?Yes. Note thatdetach()
is called on each fiber so neither of their functions is called. They are put in the background. Control passes to the fiber manager atreturn 0;
when it asks the fibers tojoin
. In fact, you can put more computations after theprintf("X");
statement, and it would be computed before any fiber is called.
As soon as we try to return from themain
, the fiber manager is asked tojoin
the fibers. The first fiberawakes,a
is printed, and the fiberyield
s the control to the manager. The fiber manager then wakes up the second fiber (who was waiting in the queue) that printsb
and also launch a thread in the background that printsB
. We can not be sure ifB
will be printed immediately after theb
(it is astd::thread
).print_b
yields the control and goes to sleep. The fiber manager wakes up first fiber again that callsprint_a
again, anda
is printed, and so on. Note thati
is incremented every time either of the fibers is called.
Wheni
hits 20, both fibers terminate andjoined
, and the main functionreturn 0;
. So we haveprint_a
called ten times, andprint_b
is also called ten times. In the output, we should have tena
s, tenb
s, and 10B
s.B
may not strictly followb
, butb
must come aftera
.
Here are a few runs of the program. Note that the location ofB
is not deterministic.
XababBabBabBababBBabBabBabBabBB
XababBabBabBabBabBabBabaBbBabBB
XababBabBabBabBabBabBabBabBabBB
XababBabBabBabBabBabBabBabBabBB
XababBabBabBBababBabBabBabBabBB
XababBabBabBabBabBabBabBabBabBB
XababBabBabBababBBabBabBababBBB
XababBabBabBababBBabBabBabBabBB
XababBabBabBababBBabBabBabBabBB
XababBabBabBabBabBababBBabBabBB
XababBabBabBabBabBabBabBabBabBB
References
- A great talk by Nat on Boost fibershttps://youtu.be/e-NUmyBou8Q
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse