Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Fiber management

Class fiber
Class fiber::id
Namespace this_fiber

Synopsis

#include <boost/fiber/all.hpp>

namespace boost {
namespace fibers {

class fiber;
bool operator<( fiber const& l, fiber const& r) noexcept;
void swap( fiber & l, fiber & r) noexcept;

template< typename SchedAlgo, typename ... Args >
void use_scheduling_algorithm( Args && ... args);
bool has_ready_fibers();

namespace algo {

struct algorithm;
template< typename PROPS >
struct algorithm_with_properties;
class round_robin;
class shared_round_robin;

}}

namespace this_fiber {

fibers::id get_id() noexcept;
void yield();
template< typename Clock, typename Duration >
void sleep_until( std::chrono::time_point< Clock, Duration > const& abs_time)
template< typename Rep, typename Period >
void sleep_for( std::chrono::duration< Rep, Period > const& rel_time);
template< typename PROPS >
PROPS & properties();

}

Tutorial

Each fiber represents a micro-thread which will be launched and managed cooperatively by a scheduler. Objects of type fiber are move-only.

boost::fibers::fiber f1; // not-a-fiber

void f() {
    boost::fibers::fiber f2( some_fn);

    f1 = std::move( f2); // f2 moved to f1
}

Launching

A new fiber is launched by passing an object of a callable type that can be invoked with no parameters. If the object must not be copied or moved, then std::ref can be used to pass in a reference to the function object. In this case, the user must ensure that the referenced object outlives the newly-created fiber.

struct callable {
    void operator()();
};

boost::fibers::fiber copies_are_safe() {
    callable x;
    return boost::fibers::fiber( x);
} // x is destroyed, but the newly-created fiber has a copy, so this is OK

boost::fibers::fiber oops() {
    callable x;
    return boost::fibers::fiber( std::ref( x) );
} // x is destroyed, but the newly-created fiber still has a reference
  // this leads to undefined behaviour

The spawned fiber does not immediately start running. It is enqueued in the list of ready-to-run fibers, and will run when the scheduler gets around to it.

Exceptions

An exception escaping from the function or callable object passed to the fiber constructor calls std::terminate(). If you need to know which exception was thrown, use future<> or packaged_task<>.

Detaching

A fiber can be detached by explicitly invoking the fiber::detach() member function. After fiber::detach() is called on a fiber object, that object represents not-a-fiber. The fiber object may then safely be destroyed.

boost::fibers::fiber( some_fn).detach();

Boost.Fiber provides a number of ways to wait for a running fiber to complete. You can coordinate even with a detached fiber using a mutex, or condition_variable, or any of the other synchronization objects provided by the library.

If a detached fiber is still running when the thread’s main fiber terminates, the thread will not shut down.

Joining

In order to wait for a fiber to finish, the fiber::join() member function of the fiber object can be used. fiber::join() will block until the fiber object has completed.

void some_fn() {
    ...
}

boost::fibers::fiber f( some_fn);
...
f.join();

If the fiber has already completed, then fiber::join() returns immediately and the joined fiber object becomes not-a-fiber.

Destruction

When a fiber object representing a valid execution context (the fiber is fiber::joinable()) is destroyed, the program terminates. If you intend the fiber to outlive the fiber object that launched it, use the fiber::detach() method.

{
    boost::fibers::fiber f( some_fn);
} // std::terminate() will be called

{
    boost::fibers::fiber f(some_fn);
    f.detach();
} // okay, program continues

Fiber IDs

Objects of class fiber::id can be used to identify fibers. Each running fiber has a unique fiber::id obtainable from the corresponding fiber by calling the fiber::get_id() member function. Objects of class fiber::id can be copied, and used as keys in associative containers: the full range of comparison operators is provided. They can also be written to an output stream using the stream insertion operator, though the output format is unspecified.

Each instance of fiber::id either refers to some fiber, or not-a-fiber. Instances that refer to not-a-fiber compare equal to each other, but not equal to any instances that refer to an actual fiber. The comparison operators on fiber::id yield a total order for every non-equal fiber::id.

Enumeration launch

launch specifies whether control passes immediately into a newly-launched fiber.

enum class launch {
    dispatch,
    post
};

dispatch

Effects:

A fiber launched with launch == dispatch is entered immediately. In other words, launching a fiber with dispatch suspends the caller (the previously-running fiber) until the fiber scheduler has a chance to resume it later.

post

Effects:

A fiber launched with launch == post is passed to the fiber scheduler as ready, but it is not yet entered. The caller (the previously-running fiber) continues executing. The newly-launched fiber will be entered when the fiber scheduler has a chance to resume it later.

Note:

If launch is not explicitly specified, post is the default.


PrevUpHomeNext