Boost fiber in your code

EventHelix
Software Design
Published in
3 min readJun 16, 2017

OK, we are not giving you dietary advice. “Boost Fiber” is a library designed to provide very light weight thread (fiber) support in user mode. A single thread can support multiple fibers that are scheduled using a fiber level scheduler running within a single thread.

Advantages of fibers over threads

  • Very fast context switch: Thread switching in operating systems is a very expensive operation that involves switching to kernel mode. A typical OS thread context switch executes in thousands of CPU cycles. Fibers on the other head can switch in about 100 CPU cycles.
  • No concurrency issues: Unlike threads, fibers are scheduled with cooperative multitasking. A fiber runs until it chooses to yield control back to the fiber scheduler. Thus fibers could update shared data structures without the risk of another fiber trampling over their updates.
  • Choose your scheduler: With threads you are stuck with the thread scheduling approaches baked into the OS. With fibers, you can choose a scheduler that is custom fitted for your application.

Boost fiber programming model

fiber construction

  • fiber represents a single fiber that is uniquely identified by the fiber::id.
  • A fiber is constructed with the callable object. Arguments may be passed to the callable object.
  • Fiber launch policy controls if the thread will be ready to run at the time of fiber creation.
template< typename Fn, typename ... Args >
fiber( Fn && fn, Args && ... args);

template< typename Fn, typename ... Args >
fiber( launch policy, Fn && fn, Args && ... args);

template< typename StackAllocator, typename Fn, typename ... Args >
fiber( std::allocator_arg_t, StackAllocator salloc, Fn && fn, Args && ... args);

this_fiber operations

The callable object running as a fiber can invoke the following APIs:

  • get_id is used to obtain the fiber identity.
  • yield The fiber relinquishes control, thus permitting the fiber manager to schedule another fiber.
  • A fiber may sleep using the sleep_until or sleep_for calls.
fibers::fiber::id get_id() noexcept;
void yield() noexcept;
template< typename Clock, typename Duration >
void sleep_until( std::chrono::time_point< Clock, Duration > const&);
template< typename Rep, typename Period >
void sleep_for( std::chrono::duration< Rep, Period > const&);

Scheduling

Boost fibers are scheduled cooperatively. When each fiber yields control, the fiber manager picks the next fiber for scheduling.

Boost fiber has a built in fiber manager that may be customized by specifying a scheduling algorithm. Any algorithm that complies with the algorithm base abstract class may be specified.

struct algorithm {
virtual ~algorithm();
virtual void awakened( context *) noexcept = 0;
virtual context * pick_next() noexcept = 0;
virtual bool has_ready_fibers() const noexcept = 0;
virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
virtual void notify() noexcept = 0;
};

Performance

Fibers offer much better performance than threads. Here are a few examples:

  • Yield (thread: 1.5 microseconds, fiber: 0.31 microseconds)
  • Creation (thread: 18 microseconds, fiber: 0.45 microseconds)

A complete set of fiber vs thread benchmarks can be found here.

Explore more

Nat Goodspeed’s talk is a good introduction to fibers.

Mark Papadakis’s blog post is an excellent introduction to the world of fibers:

--

--