]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | Copyright Oliver Kowalke 2013. | |
3 | Distributed under the Boost Software License, Version 1.0. | |
4 | (See accompanying file LICENSE_1_0.txt or copy at | |
5 | http://www.boost.org/LICENSE_1_0.txt | |
6 | ] | |
7 | ||
8 | [section:overview Overview] | |
9 | ||
10 | __boost_fiber__ provides a framework for micro-/userland-threads (fibers) | |
11 | scheduled cooperatively. | |
12 | The API contains classes and functions to manage and synchronize fibers similiarly to | |
13 | __std_thread__. | |
14 | ||
15 | Each fiber has its own stack. | |
16 | ||
17 | A fiber can save the current execution state, including all registers | |
18 | and CPU flags, the instruction pointer, and the stack pointer and later restore | |
19 | this state. | |
20 | The idea is to have multiple execution paths running on a single thread using | |
21 | cooperative scheduling (versus threads, which are preemptively scheduled). The | |
22 | running fiber decides explicitly when it should yield to allow another fiber to | |
23 | run (context switching). | |
24 | __boost_fiber__ internally uses __econtext__ from __boost_context__; the classes in | |
25 | this library manage, schedule and, when needed, synchronize those execution contexts. | |
26 | A context switch between threads usually costs thousands of CPU cycles on x86, | |
27 | compared to a fiber switch with less than a hundred cycles. | |
28 | A fiber runs on a single thread at any point in time. | |
29 | ||
30 | In order to use the classes and functions described here, you can either include | |
31 | the specific headers specified by the descriptions of each class or function, or | |
32 | include the master library header: | |
33 | ||
34 | #include <boost/fiber/all.hpp> | |
35 | ||
36 | which includes all the other headers in turn. | |
37 | ||
38 | The namespaces used are: | |
39 | ||
40 | namespace boost::fibers | |
41 | namespace boost::this_fiber | |
42 | ||
43 | [heading Fibers and Threads] | |
44 | ||
45 | Control is cooperatively passed between fibers launched on a given thread. At | |
46 | a given moment, on a given thread, at most one fiber is running. | |
47 | ||
48 | Spawning additional fibers on a given thread does not distribute your program | |
49 | across more hardware cores, though it can make more effective use of the core | |
50 | on which it's running. | |
51 | ||
52 | On the other hand, a fiber may safely access any resource exclusively owned by | |
53 | its parent thread without explicitly needing to defend that resource against | |
54 | concurrent access by other fibers on the same thread. You are already | |
55 | guaranteed that no other fiber on that thread is concurrently touching that | |
56 | resource. This can be particularly important when introducing concurrency in | |
57 | legacy code. You can safely spawn fibers running old code, using asynchronous | |
58 | I/O to interleave execution. | |
59 | ||
60 | In effect, fibers provide a natural way to organize concurrent code based on | |
61 | asynchronous I/O. Instead of chaining together completion handlers, code | |
62 | running on a fiber can make what looks like a normal blocking function call. | |
63 | That call can cheaply suspend the calling fiber, allowing other fibers on the | |
64 | same thread to run. When the operation has completed, the suspended fiber | |
65 | resumes, without having to explicitly save or restore its state. Its local | |
66 | stack variables persist across the call. | |
67 | ||
68 | A fiber can be migrated from one thread to another, though the library does | |
69 | not do this by default. It is possible for you to supply a custom scheduler | |
70 | that migrates fibers between threads. You may specify custom fiber properties | |
71 | to help your scheduler decide which fibers are permitted to migrate. Please | |
72 | see [link migration Migrating fibers between threads] and [link custom | |
73 | Customization] for more details. | |
74 | ||
75 | A fiber launched on a particular thread continues running on that thread | |
76 | unless migrated. It might be unblocked (see [link blocking Blocking] below) by | |
77 | some other thread, but that only transitions the fiber from ["blocked] to | |
78 | ["ready] on its current thread [mdash] it does not cause the fiber to | |
79 | resume on the thread that unblocked it. | |
80 | ||
81 | [#thread_local_storage] | |
82 | [heading thread-local storage] | |
83 | Unless migrated, a fiber may access thread-local storage; however that storage | |
84 | will be shared among all fibers running on the same thread. For fiber-local | |
85 | storage, please see __fsp__. | |
86 | ||
87 | [#cross_thread_sync] | |
88 | [heading BOOST_FIBERS_NO_ATOMICS] | |
89 | The fiber synchronization objects provided by this library will, by default, | |
90 | safely synchronize fibers running on different threads. However, this level of | |
91 | synchronization can be removed (for performance) by building the library with | |
92 | [*`BOOST_FIBERS_NO_ATOMICS`] defined. When the library is built with that macro, | |
93 | you must ensure that all the fibers referencing a particular synchronization | |
94 | object are running in the same thread. Please see [link synchronization | |
95 | Synchronization]. | |
96 | ||
97 | [#blocking] | |
98 | [heading Blocking] | |
99 | ||
100 | Normally, when this documentation states that a particular fiber ['blocks] (or | |
101 | equivalently, ['suspends),] it means that it yields control, allowing other | |
102 | fibers on the same thread to run. The synchronization mechanisms provided by | |
103 | __boost_fiber__ have this behavior. | |
104 | ||
105 | A fiber may, of course, use normal thread synchronization mechanisms; however | |
106 | a fiber that invokes any of these mechanisms will block its entire thread, | |
107 | preventing any other fiber from running on that thread in the meantime. For | |
108 | instance, when a fiber wants to wait for a value from another fiber in the | |
109 | same thread, using `std::future` would be unfortunate: `std::future::get()` would | |
110 | block the whole thread, preventing the other fiber from delivering its value. | |
111 | Use __future__ instead. | |
112 | ||
113 | Similarly, a fiber that invokes a normal blocking I/O operation will block its | |
114 | entire thread. Fiber authors are encouraged to consistently use asynchronous | |
115 | I/O. __boost_asio__ and other asynchronous I/O operations can | |
116 | straightforwardly be adapted for __boost_fiber__: see [link callbacks | |
117 | Integrating Fibers with Asynchronous Callbacks]. | |
118 | ||
119 | __boost_fiber__ depends upon __boost_context__. | |
120 | Boost version 1.61.0 or greater is required. | |
121 | ||
122 | [note This library requires C++11!] | |
123 | ||
124 | ||
125 | [endsect] |