...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Table 1.6. preopcessor defines
BOOST_FIBERS_NO_ATOMICS |
no |
BOOST_FIBERS_SPINLOCK_STD_MUTEX |
use |
BOOST_FIBERS_SPIN_BACKOFF |
limit determines when to used |
BOOST_FIBERS_SINGLE_CORE |
allways call |
The fiber library extends the coroutine library by adding a scheduler and synchronization mechanisms.
When a coroutine yields, it passes control directly to its caller (or, in the case of symmetric coroutines, a designated other coroutine). When a fiber blocks, it implicitly passes control to the fiber scheduler. Coroutines have no scheduler because they need no scheduler.[12].
GCC supports transactional memory since version 4.7. Unfortunately tests show that transactional memory is slower (ca. 4x) than spinlocks using atomics. Once transactional memory is improved (supporting hybrid tm), spinlocks will be replaced by __transaction_atomic{} statements surrounding the critical sections.
Synchronization classes from Boost.Thread block the entire thread. In contrast, the synchronization classes from Boost.Fiber block only specific fibers, so that the scheduler can still keep the thread busy running other fibers in the meantime. The synchronization classes from Boost.Fiber are designed to be thread-safe, i.e. it is possible to synchronize fibers running in different threads as well as fibers running in the same thread. (However, there is a build option to disable cross-thread fiber synchronization support; see this description.)
Spurious wakeup can happen when using std::condition_variable
:
the condition variable appears to be have been signaled while the awaited condition
may still be false. Spurious wakeup can happen repeatedly and is caused on
some multiprocessor systems where making std::condition_variable
wakeup completely predictable would slow down all std::condition_variable
operations.[13]
condition_variable
is not subject to spurious wakeup.
Nonetheless it is prudent to test the business-logic condition in a wait()
loop
— or, equivalently, use one of the wait( lock,
predicate )
overloads.
See also No Spurious Wakeups.
Support for migrating fibers between threads has been integrated. The user-defined
scheduler must call context::detach()
on a fiber-context on the
source thread and context::attach()
on the destination thread,
passing the fiber-context to migrate. (For more information about custom schedulers,
see Customization.) Examples work_sharing
and work_stealing
in directory
examples
might be used as a
blueprint.
See also Migrating fibers between threads.
Support for Boost.Asio’s
async-result is not part of the official API. However,
to integrate with a boost::asio::io_service
,
see Sharing a Thread with Another Main Loop.
To interface smoothly with an arbitrary Asio async I/O operation, see Then There’s Boost.Asio.
The library was tested with GCC-5.1.1, Clang-3.6.0 and MSVC-14.0 in c++11-mode.
Boost.Fiber depends on Boost.Context - the list of supported architectures can be found here.