| Home | Libraries | People | FAQ | More

## Fiber management

#### 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.