...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Consider a classic event-driven program, organized around a main loop that fetches and dispatches incoming I/O events. You are introducing Boost.Fiber because certain asynchronous I/O sequences are logically sequential, and for those you want to write and maintain code that looks and acts sequential.
You are launching fibers on the application’s main thread because certain of their actions will affect its user interface, and the application’s UI framework permits UI operations only on the main thread. Or perhaps those fibers need access to main-thread data, and it would be too expensive in runtime (or development time) to robustly defend every such data item with thread synchronization primitives.
You must ensure that the application’s main loop itself doesn’t monopolize the processor: that the fibers it launches will get the CPU cycles they need.
The solution is the same as for any fiber that might claim the CPU for an
extended time: introduce calls to this_fiber::yield()
. The
most straightforward approach is to call yield()
on every iteration of your existing main
loop. In effect, this unifies the application’s main loop with Boost.Fiber’s
internal main loop. yield()
allows the fiber manager to run any fibers
that have become ready since the previous iteration of the application’s main
loop. When these fibers have had a turn, control passes to the thread’s main
fiber, which returns from yield()
and resumes the application’s main loop.