Boost fiber in your code
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 thefiber::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
orsleep_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: