3 <meta http-equiv=
"Content-Type" content=
"text/html; charset=US-ASCII">
4 <title>Migrating fibers between threads
</title>
5 <link rel=
"stylesheet" href=
"../../../../../doc/src/boostbook.css" type=
"text/css">
6 <meta name=
"generator" content=
"DocBook XSL Stylesheets V1.75.2">
7 <link rel=
"home" href=
"../index.html" title=
"Chapter 1. Fiber">
8 <link rel=
"up" href=
"../index.html" title=
"Chapter 1. Fiber">
9 <link rel=
"prev" href=
"fls.html" title=
"Fiber local storage">
10 <link rel=
"next" href=
"callbacks.html" title=
"Integrating Fibers with Asynchronous Callbacks">
12 <body bgcolor=
"white" text=
"black" link=
"#0000FF" vlink=
"#840084" alink=
"#0000FF">
13 <table cellpadding=
"2" width=
"100%"><tr>
14 <td valign=
"top"><img alt=
"Boost C++ Libraries" width=
"277" height=
"86" src=
"../../../../../boost.png"></td>
15 <td align=
"center"><a href=
"../../../../../index.html">Home
</a></td>
16 <td align=
"center"><a href=
"../../../../../libs/libraries.htm">Libraries
</a></td>
17 <td align=
"center"><a href=
"http://www.boost.org/users/people.html">People
</a></td>
18 <td align=
"center"><a href=
"http://www.boost.org/users/faq.html">FAQ
</a></td>
19 <td align=
"center"><a href=
"../../../../../more/index.htm">More
</a></td>
22 <div class=
"spirit-nav">
23 <a accesskey=
"p" href=
"fls.html"><img src=
"../../../../../doc/src/images/prev.png" alt=
"Prev"></a><a accesskey=
"u" href=
"../index.html"><img src=
"../../../../../doc/src/images/up.png" alt=
"Up"></a><a accesskey=
"h" href=
"../index.html"><img src=
"../../../../../doc/src/images/home.png" alt=
"Home"></a><a accesskey=
"n" href=
"callbacks.html"><img src=
"../../../../../doc/src/images/next.png" alt=
"Next"></a>
26 <div class=
"titlepage"><div><div><h2 class=
"title" style=
"clear: both">
27 <a name=
"fiber.migration"></a><a name=
"migration"></a><a class=
"link" href=
"migration.html" title=
"Migrating fibers between threads">Migrating fibers
29 </h2></div></div></div>
31 <a name=
"fiber.migration.h0"></a>
32 <span><a name=
"fiber.migration.overview"></a></span><a class=
"link" href=
"migration.html#fiber.migration.overview">Overview
</a>
35 Each fiber owns a stack and manages its execution state, including all registers
36 and CPU flags, the instruction pointer and the stack pointer. That means, in
37 general, a fiber is not bound to a specific thread.
<sup>[
<a name=
"fiber.migration.f0" href=
"#ftn.fiber.migration.f0" class=
"footnote">2</a>]
</sup><sup>,
</sup><sup>[
<a name=
"fiber.migration.f1" href=
"#ftn.fiber.migration.f1" class=
"footnote">3</a>]
</sup>
40 Migrating a fiber from a logical CPU with heavy workload to another logical
41 CPU with a lighter workload might speed up the overall execution. Note that
42 in the case of NUMA-architectures, it is not always advisable to migrate data
43 between threads. Suppose fiber
<span class=
"emphasis"><em>f
</em></span> is running on logical
44 CPU
<span class=
"emphasis"><em>cpu0
</em></span> which belongs to NUMA node
<span class=
"emphasis"><em>node0
</em></span>.
45 The data of
<span class=
"emphasis"><em>f
</em></span> are allocated on the physical memory located
46 at
<span class=
"emphasis"><em>node0
</em></span>. Migrating the fiber from
<span class=
"emphasis"><em>cpu0
</em></span>
47 to another logical CPU
<span class=
"emphasis"><em>cpuX
</em></span> which is part of a different
48 NUMA node
<span class=
"emphasis"><em>nodeX
</em></span> might reduce the performance of the application
49 due to increased latency of memory access.
52 Only fibers that are contained in
<a class=
"link" href=
"scheduling.html#class_algorithm"><code class=
"computeroutput">algorithm
</code></a>’s ready queue can
53 migrate between threads. You cannot migrate a running fiber, nor one that is
54 <a class=
"link" href=
"overview.html#blocking"><span class=
"emphasis"><em>blocked
</em></span></a>. You cannot migrate
55 a fiber if its
<a class=
"link" href=
"scheduling.html#context_is_context"><code class=
"computeroutput">context::is_context()
</code></a> method returns
<code class=
"computeroutput"><span class=
"keyword">true
</span></code> for
<code class=
"computeroutput"><span class=
"identifier">pinned_context
</span></code>.
58 In
<span class=
"bold"><strong>Boost.Fiber
</strong></span> a fiber is migrated by invoking
59 <a class=
"link" href=
"scheduling.html#context_detach"><code class=
"computeroutput">context::detach()
</code></a> on the thread from which the fiber migrates
60 and
<a class=
"link" href=
"scheduling.html#context_attach"><code class=
"computeroutput">context::attach()
</code></a> on the thread to which the fiber migrates.
63 Thus, fiber migration is accomplished by sharing state between instances of
64 a user-coded
<a class=
"link" href=
"scheduling.html#class_algorithm"><code class=
"computeroutput">algorithm
</code></a> implementation running on different threads.
65 The fiber
’s original thread calls
<a class=
"link" href=
"scheduling.html#algorithm_awakened"><code class=
"computeroutput">algorithm::awakened()
</code></a>, passing
66 the fiber
’s
<a class=
"link" href=
"scheduling.html#class_context"><code class=
"computeroutput">context
</code></a><code class=
"literal">*
</code>. The
<code class=
"computeroutput"><span class=
"identifier">awakened
</span><span class=
"special">()
</span></code> implementation calls
<a class=
"link" href=
"scheduling.html#context_detach"><code class=
"computeroutput">context::detach()
</code></a>.
69 At some later point, when the same or a different thread calls
<a class=
"link" href=
"scheduling.html#algorithm_pick_next"><code class=
"computeroutput">algorithm::pick_next()
</code></a>,
70 the
<code class=
"computeroutput"><span class=
"identifier">pick_next
</span><span class=
"special">()
</span></code>
71 implementation selects a ready fiber and calls
<a class=
"link" href=
"scheduling.html#context_attach"><code class=
"computeroutput">context::attach()
</code></a> on
72 it before returning it.
75 As stated above, a
<code class=
"computeroutput"><span class=
"identifier">context
</span></code>
76 for which
<code class=
"computeroutput"><span class=
"identifier">is_context
</span><span class=
"special">(
</span><span class=
"identifier">pinned_context
</span><span class=
"special">)
</span>
77 <span class=
"special">==
</span> <span class=
"keyword">true
</span></code>
78 must never be passed to either
<a class=
"link" href=
"scheduling.html#context_detach"><code class=
"computeroutput">context::detach()
</code></a> or
<a class=
"link" href=
"scheduling.html#context_attach"><code class=
"computeroutput">context::attach()
</code></a>.
79 It may only be returned from
<code class=
"computeroutput"><span class=
"identifier">pick_next
</span><span class=
"special">()
</span></code> called by the
<span class=
"emphasis"><em>same
</em></span> thread
80 that passed that context to
<code class=
"computeroutput"><span class=
"identifier">awakened
</span><span class=
"special">()
</span></code>.
83 <a name=
"fiber.migration.h1"></a>
84 <span><a name=
"fiber.migration.example_of_work_sharing"></a></span><a class=
"link" href=
"migration.html#fiber.migration.example_of_work_sharing">Example
88 In the example
<a href=
"../../../examples/work_sharing.cpp" target=
"_top">work_sharing.cpp
</a>
89 multiple worker fibers are created on the main thread. Each fiber gets a character
90 as parameter at construction. This character is printed out ten times. Between
91 each iteration the fiber calls
<a class=
"link" href=
"fiber_mgmt/this_fiber.html#this_fiber_yield"><code class=
"computeroutput">this_fiber::yield()
</code></a>. That puts
92 the fiber in the ready queue of the fiber-scheduler
<span class=
"emphasis"><em>shared_ready_queue
</em></span>,
93 running in the current thread. The next fiber ready to be executed is dequeued
94 from the shared ready queue and resumed by
<span class=
"emphasis"><em>shared_ready_queue
</em></span>
95 running on
<span class=
"emphasis"><em>any participating thread
</em></span>.
98 All instances of
<span class=
"emphasis"><em>shared_ready_queue
</em></span> share one global concurrent
99 queue, used as ready queue. This mechanism shares all worker fibers between
100 all instances of
<span class=
"emphasis"><em>shared_ready_queue
</em></span>, thus between all
101 participating threads.
104 <a name=
"fiber.migration.h2"></a>
105 <span><a name=
"fiber.migration.setup_of_threads_and_fibers"></a></span><a class=
"link" href=
"migration.html#fiber.migration.setup_of_threads_and_fibers">Setup
106 of threads and fibers
</a>
109 In
<code class=
"computeroutput"><span class=
"identifier">main
</span><span class=
"special">()
</span></code>
110 the fiber-scheduler is installed and the worker fibers and the threads are
115 <pre class=
"programlisting"><span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">use_scheduling_algorithm
</span><span class=
"special"><</span> <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">algo
</span><span class=
"special">::
</span><span class=
"identifier">shared_work
</span> <span class=
"special">>();
</span> <a class=
"co" name=
"fiber.migration.c0" href=
"migration.html#fiber.migration.c1"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a>
117 <span class=
"keyword">for
</span> <span class=
"special">(
</span> <span class=
"keyword">char
</span> <span class=
"identifier">c
</span> <span class=
"special">:
</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">string
</span><span class=
"special">(
</span><span class=
"string">"abcdefghijklmnopqrstuvwxyz"</span><span class=
"special">))
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c2" href=
"migration.html#fiber.migration.c3"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a>
118 <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">fiber
</span><span class=
"special">([
</span><span class=
"identifier">c
</span><span class=
"special">](){
</span> <span class=
"identifier">whatevah
</span><span class=
"special">(
</span> <span class=
"identifier">c
</span><span class=
"special">);
</span> <span class=
"special">}).
</span><span class=
"identifier">detach
</span><span class=
"special">();
</span>
119 <span class=
"special">++
</span><span class=
"identifier">fiber_count
</span><span class=
"special">;
</span> <a class=
"co" name=
"fiber.migration.c4" href=
"migration.html#fiber.migration.c5"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a>
120 <span class=
"special">}
</span>
121 <span class=
"identifier">barrier
</span> <span class=
"identifier">b
</span><span class=
"special">(
</span> <span class=
"number">4</span><span class=
"special">);
</span>
122 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span> <span class=
"identifier">threads
</span><span class=
"special">[]
</span> <span class=
"special">=
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c6" href=
"migration.html#fiber.migration.c7"><img src=
"../../../../../doc/src/images/callouts/4.png" alt=
"4" border=
"0"></a>
123 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span><span class=
"special">(
</span> <span class=
"identifier">thread
</span><span class=
"special">,
</span> <span class=
"special">&</span> <span class=
"identifier">b
</span><span class=
"special">),
</span>
124 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span><span class=
"special">(
</span> <span class=
"identifier">thread
</span><span class=
"special">,
</span> <span class=
"special">&</span> <span class=
"identifier">b
</span><span class=
"special">),
</span>
125 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span><span class=
"special">(
</span> <span class=
"identifier">thread
</span><span class=
"special">,
</span> <span class=
"special">&</span> <span class=
"identifier">b
</span><span class=
"special">)
</span>
126 <span class=
"special">};
</span>
127 <span class=
"identifier">b
</span><span class=
"special">.
</span><span class=
"identifier">wait
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c8" href=
"migration.html#fiber.migration.c9"><img src=
"../../../../../doc/src/images/callouts/5.png" alt=
"5" border=
"0"></a>
128 <span class=
"special">{
</span>
129 <span class=
"identifier">lock_t
</span><a class=
"co" name=
"fiber.migration.c10" href=
"migration.html#fiber.migration.c11"><img src=
"../../../../../doc/src/images/callouts/6.png" alt=
"6" border=
"0"></a> <span class=
"identifier">lk
</span><span class=
"special">(
</span> <span class=
"identifier">mtx_count
</span><span class=
"special">);
</span>
130 <span class=
"identifier">cnd_count
</span><span class=
"special">.
</span><span class=
"identifier">wait
</span><span class=
"special">(
</span> <span class=
"identifier">lk
</span><span class=
"special">,
</span> <span class=
"special">[](){
</span> <span class=
"keyword">return
</span> <span class=
"number">0</span> <span class=
"special">==
</span> <span class=
"identifier">fiber_count
</span><span class=
"special">;
</span> <span class=
"special">}
</span> <span class=
"special">);
</span> <a class=
"co" name=
"fiber.migration.c12" href=
"migration.html#fiber.migration.c13"><img src=
"../../../../../doc/src/images/callouts/7.png" alt=
"7" border=
"0"></a>
131 <span class=
"special">}
</span> <a class=
"co" name=
"fiber.migration.c14" href=
"migration.html#fiber.migration.c15"><img src=
"../../../../../doc/src/images/callouts/8.png" alt=
"8" border=
"0"></a>
132 <span class=
"identifier">BOOST_ASSERT
</span><span class=
"special">(
</span> <span class=
"number">0</span> <span class=
"special">==
</span> <span class=
"identifier">fiber_count
</span><span class=
"special">);
</span>
133 <span class=
"keyword">for
</span> <span class=
"special">(
</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span> <span class=
"special">&</span> <span class=
"identifier">t
</span> <span class=
"special">:
</span> <span class=
"identifier">threads
</span><span class=
"special">)
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c16" href=
"migration.html#fiber.migration.c17"><img src=
"../../../../../doc/src/images/callouts/9.png" alt=
"9" border=
"0"></a>
134 <span class=
"identifier">t
</span><span class=
"special">.
</span><span class=
"identifier">join
</span><span class=
"special">();
</span>
135 <span class=
"special">}
</span>
139 <div class=
"calloutlist"><table border=
"0" summary=
"Callout list">
141 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c1"></a><a href=
"#fiber.migration.c0"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a> </p></td>
142 <td valign=
"top" align=
"left"><p>
143 Install the scheduling algorithm
<code class=
"computeroutput"><span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">algo
</span><span class=
"special">::
</span><span class=
"identifier">shared_work
</span></code>
144 in the main thread too, so each new fiber gets launched into the shared
149 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c3"></a><a href=
"#fiber.migration.c2"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a> </p></td>
150 <td valign=
"top" align=
"left"><p>
151 Launch a number of worker fibers; each worker fiber picks up a character
152 that is passed as parameter to fiber-function
<code class=
"computeroutput"><span class=
"identifier">whatevah
</span></code>.
153 Each worker fiber gets detached.
157 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c5"></a><a href=
"#fiber.migration.c4"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a> </p></td>
158 <td valign=
"top" align=
"left"><p>
159 Increment fiber counter for each new fiber.
163 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c7"></a><a href=
"#fiber.migration.c6"><img src=
"../../../../../doc/src/images/callouts/4.png" alt=
"4" border=
"0"></a> </p></td>
164 <td valign=
"top" align=
"left"><p>
165 Launch a couple of threads that join the work sharing.
169 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c9"></a><a href=
"#fiber.migration.c8"><img src=
"../../../../../doc/src/images/callouts/5.png" alt=
"5" border=
"0"></a> </p></td>
170 <td valign=
"top" align=
"left"><p>
171 sync with other threads: allow them to start processing
175 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c11"></a><a href=
"#fiber.migration.c10"><img src=
"../../../../../doc/src/images/callouts/6.png" alt=
"6" border=
"0"></a> </p></td>
176 <td valign=
"top" align=
"left"><p>
177 <code class=
"computeroutput"><span class=
"identifier">lock_t
</span></code> is typedef'ed as
178 <a href=
"http://en.cppreference.com/w/cpp/thread/unique_lock" target=
"_top"><code class=
"computeroutput"><span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">unique_lock
</span></code></a>< <a href=
"http://en.cppreference.com/w/cpp/thread/mutex" target=
"_top"><code class=
"computeroutput"><span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">mutex
</span></code></a> >
182 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c13"></a><a href=
"#fiber.migration.c12"><img src=
"../../../../../doc/src/images/callouts/7.png" alt=
"7" border=
"0"></a> </p></td>
183 <td valign=
"top" align=
"left"><p>
184 Suspend main fiber and resume worker fibers in the meanwhile. Main fiber
185 gets resumed (e.g returns from
<code class=
"computeroutput"><span class=
"identifier">condition_variable_any
</span><span class=
"special">::
</span><span class=
"identifier">wait
</span><span class=
"special">()
</span></code>) if all worker fibers are complete.
189 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c15"></a><a href=
"#fiber.migration.c14"><img src=
"../../../../../doc/src/images/callouts/8.png" alt=
"8" border=
"0"></a> </p></td>
190 <td valign=
"top" align=
"left"><p>
191 Releasing lock of mtx_count is required before joining the threads, otherwise
192 the other threads would be blocked inside condition_variable::wait() and
193 would never return (deadlock).
197 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c17"></a><a href=
"#fiber.migration.c16"><img src=
"../../../../../doc/src/images/callouts/9.png" alt=
"9" border=
"0"></a> </p></td>
198 <td valign=
"top" align=
"left"><p>
199 wait for threads to terminate
204 The start of the threads is synchronized with a barrier. The main fiber of
205 each thread (including main thread) is suspended until all worker fibers are
206 complete. When the main fiber returns from
<a class=
"link" href=
"synchronization/conditions.html#condition_variable_wait"><code class=
"computeroutput">condition_variable::wait()
</code></a>,
207 the thread terminates: the main thread joins all other threads.
211 <pre class=
"programlisting"><span class=
"keyword">void
</span> <span class=
"identifier">thread
</span><span class=
"special">(
</span> <span class=
"identifier">barrier
</span> <span class=
"special">*
</span> <span class=
"identifier">b
</span><span class=
"special">)
</span> <span class=
"special">{
</span>
212 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">ostringstream
</span> <span class=
"identifier">buffer
</span><span class=
"special">;
</span>
213 <span class=
"identifier">buffer
</span> <span class=
"special"><<</span> <span class=
"string">"thread started "</span> <span class=
"special"><<</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">this_thread
</span><span class=
"special">::
</span><span class=
"identifier">get_id
</span><span class=
"special">()
</span> <span class=
"special"><<</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">endl
</span><span class=
"special">;
</span>
214 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">cout
</span> <span class=
"special"><<</span> <span class=
"identifier">buffer
</span><span class=
"special">.
</span><span class=
"identifier">str
</span><span class=
"special">()
</span> <span class=
"special"><<</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">flush
</span><span class=
"special">;
</span>
215 <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">use_scheduling_algorithm
</span><span class=
"special"><</span> <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">algo
</span><span class=
"special">::
</span><span class=
"identifier">shared_work
</span> <span class=
"special">>();
</span> <a class=
"co" name=
"fiber.migration.c18" href=
"migration.html#fiber.migration.c19"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a>
216 <span class=
"identifier">b
</span><span class=
"special">-
></span><span class=
"identifier">wait
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c20" href=
"migration.html#fiber.migration.c21"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a>
217 <span class=
"identifier">lock_t
</span> <span class=
"identifier">lk
</span><span class=
"special">(
</span> <span class=
"identifier">mtx_count
</span><span class=
"special">);
</span>
218 <span class=
"identifier">cnd_count
</span><span class=
"special">.
</span><span class=
"identifier">wait
</span><span class=
"special">(
</span> <span class=
"identifier">lk
</span><span class=
"special">,
</span> <span class=
"special">[](){
</span> <span class=
"keyword">return
</span> <span class=
"number">0</span> <span class=
"special">==
</span> <span class=
"identifier">fiber_count
</span><span class=
"special">;
</span> <span class=
"special">}
</span> <span class=
"special">);
</span> <a class=
"co" name=
"fiber.migration.c22" href=
"migration.html#fiber.migration.c23"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a>
219 <span class=
"identifier">BOOST_ASSERT
</span><span class=
"special">(
</span> <span class=
"number">0</span> <span class=
"special">==
</span> <span class=
"identifier">fiber_count
</span><span class=
"special">);
</span>
220 <span class=
"special">}
</span>
224 <div class=
"calloutlist"><table border=
"0" summary=
"Callout list">
226 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c19"></a><a href=
"#fiber.migration.c18"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a> </p></td>
227 <td valign=
"top" align=
"left"><p>
228 Install the scheduling algorithm
<code class=
"computeroutput"><span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">fibers
</span><span class=
"special">::
</span><span class=
"identifier">algo
</span><span class=
"special">::
</span><span class=
"identifier">shared_work
</span></code>
229 in order to join the work sharing.
233 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c21"></a><a href=
"#fiber.migration.c20"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a> </p></td>
234 <td valign=
"top" align=
"left"><p>
235 sync with other threads: allow them to start processing
239 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c23"></a><a href=
"#fiber.migration.c22"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a> </p></td>
240 <td valign=
"top" align=
"left"><p>
241 Suspend main fiber and resume worker fibers in the meanwhile. Main fiber
242 gets resumed (e.g returns from
<code class=
"computeroutput"><span class=
"identifier">condition_variable_any
</span><span class=
"special">::
</span><span class=
"identifier">wait
</span><span class=
"special">()
</span></code>) if all worker fibers are complete.
247 Each worker fiber executes function
<code class=
"computeroutput"><span class=
"identifier">whatevah
</span><span class=
"special">()
</span></code> with character
<code class=
"computeroutput"><span class=
"identifier">me
</span></code>
248 as parameter. The fiber yields in a loop and prints out a message if it was
249 migrated to another thread.
253 <pre class=
"programlisting"><span class=
"keyword">void
</span> <span class=
"identifier">whatevah
</span><span class=
"special">(
</span> <span class=
"keyword">char
</span> <span class=
"identifier">me
</span><span class=
"special">)
</span> <span class=
"special">{
</span>
254 <span class=
"keyword">try
</span> <span class=
"special">{
</span>
255 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span><span class=
"special">::
</span><span class=
"identifier">id
</span> <span class=
"identifier">my_thread
</span> <span class=
"special">=
</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">this_thread
</span><span class=
"special">::
</span><span class=
"identifier">get_id
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c24" href=
"migration.html#fiber.migration.c25"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a>
256 <span class=
"special">{
</span>
257 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">ostringstream
</span> <span class=
"identifier">buffer
</span><span class=
"special">;
</span>
258 <span class=
"identifier">buffer
</span> <span class=
"special"><<</span> <span class=
"string">"fiber "</span> <span class=
"special"><<</span> <span class=
"identifier">me
</span> <span class=
"special"><<</span> <span class=
"string">" started on thread "</span> <span class=
"special"><<</span> <span class=
"identifier">my_thread
</span> <span class=
"special"><<</span> <span class=
"char">'\n'
</span><span class=
"special">;
</span>
259 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">cout
</span> <span class=
"special"><<</span> <span class=
"identifier">buffer
</span><span class=
"special">.
</span><span class=
"identifier">str
</span><span class=
"special">()
</span> <span class=
"special"><<</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">flush
</span><span class=
"special">;
</span>
260 <span class=
"special">}
</span>
261 <span class=
"keyword">for
</span> <span class=
"special">(
</span> <span class=
"keyword">unsigned
</span> <span class=
"identifier">i
</span> <span class=
"special">=
</span> <span class=
"number">0</span><span class=
"special">;
</span> <span class=
"identifier">i
</span> <span class=
"special"><</span> <span class=
"number">10</span><span class=
"special">;
</span> <span class=
"special">++
</span><span class=
"identifier">i
</span><span class=
"special">)
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c26" href=
"migration.html#fiber.migration.c27"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a>
262 <span class=
"identifier">boost
</span><span class=
"special">::
</span><span class=
"identifier">this_fiber
</span><span class=
"special">::
</span><span class=
"identifier">yield
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c28" href=
"migration.html#fiber.migration.c29"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a>
263 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">thread
</span><span class=
"special">::
</span><span class=
"identifier">id
</span> <span class=
"identifier">new_thread
</span> <span class=
"special">=
</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">this_thread
</span><span class=
"special">::
</span><span class=
"identifier">get_id
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c30" href=
"migration.html#fiber.migration.c31"><img src=
"../../../../../doc/src/images/callouts/4.png" alt=
"4" border=
"0"></a>
264 <span class=
"keyword">if
</span> <span class=
"special">(
</span> <span class=
"identifier">new_thread
</span> <span class=
"special">!=
</span> <span class=
"identifier">my_thread
</span><span class=
"special">)
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c32" href=
"migration.html#fiber.migration.c33"><img src=
"../../../../../doc/src/images/callouts/5.png" alt=
"5" border=
"0"></a>
265 <span class=
"identifier">my_thread
</span> <span class=
"special">=
</span> <span class=
"identifier">new_thread
</span><span class=
"special">;
</span>
266 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">ostringstream
</span> <span class=
"identifier">buffer
</span><span class=
"special">;
</span>
267 <span class=
"identifier">buffer
</span> <span class=
"special"><<</span> <span class=
"string">"fiber "</span> <span class=
"special"><<</span> <span class=
"identifier">me
</span> <span class=
"special"><<</span> <span class=
"string">" switched to thread "</span> <span class=
"special"><<</span> <span class=
"identifier">my_thread
</span> <span class=
"special"><<</span> <span class=
"char">'\n'
</span><span class=
"special">;
</span>
268 <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">cout
</span> <span class=
"special"><<</span> <span class=
"identifier">buffer
</span><span class=
"special">.
</span><span class=
"identifier">str
</span><span class=
"special">()
</span> <span class=
"special"><<</span> <span class=
"identifier">std
</span><span class=
"special">::
</span><span class=
"identifier">flush
</span><span class=
"special">;
</span>
269 <span class=
"special">}
</span>
270 <span class=
"special">}
</span>
271 <span class=
"special">}
</span> <span class=
"keyword">catch
</span> <span class=
"special">(
</span> <span class=
"special">...
</span> <span class=
"special">)
</span> <span class=
"special">{
</span>
272 <span class=
"special">}
</span>
273 <span class=
"identifier">lock_t
</span> <span class=
"identifier">lk
</span><span class=
"special">(
</span> <span class=
"identifier">mtx_count
</span><span class=
"special">);
</span>
274 <span class=
"keyword">if
</span> <span class=
"special">(
</span> <span class=
"number">0</span> <span class=
"special">==
</span> <span class=
"special">--
</span><span class=
"identifier">fiber_count
</span><span class=
"special">)
</span> <span class=
"special">{
</span> <a class=
"co" name=
"fiber.migration.c34" href=
"migration.html#fiber.migration.c35"><img src=
"../../../../../doc/src/images/callouts/6.png" alt=
"6" border=
"0"></a>
275 <span class=
"identifier">lk
</span><span class=
"special">.
</span><span class=
"identifier">unlock
</span><span class=
"special">();
</span>
276 <span class=
"identifier">cnd_count
</span><span class=
"special">.
</span><span class=
"identifier">notify_all
</span><span class=
"special">();
</span> <a class=
"co" name=
"fiber.migration.c36" href=
"migration.html#fiber.migration.c37"><img src=
"../../../../../doc/src/images/callouts/7.png" alt=
"7" border=
"0"></a>
277 <span class=
"special">}
</span>
278 <span class=
"special">}
</span>
282 <div class=
"calloutlist"><table border=
"0" summary=
"Callout list">
284 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c25"></a><a href=
"#fiber.migration.c24"><img src=
"../../../../../doc/src/images/callouts/1.png" alt=
"1" border=
"0"></a> </p></td>
285 <td valign=
"top" align=
"left"><p>
286 get ID of initial thread
290 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c27"></a><a href=
"#fiber.migration.c26"><img src=
"../../../../../doc/src/images/callouts/2.png" alt=
"2" border=
"0"></a> </p></td>
291 <td valign=
"top" align=
"left"><p>
296 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c29"></a><a href=
"#fiber.migration.c28"><img src=
"../../../../../doc/src/images/callouts/3.png" alt=
"3" border=
"0"></a> </p></td>
297 <td valign=
"top" align=
"left"><p>
298 yield to other fibers
302 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c31"></a><a href=
"#fiber.migration.c30"><img src=
"../../../../../doc/src/images/callouts/4.png" alt=
"4" border=
"0"></a> </p></td>
303 <td valign=
"top" align=
"left"><p>
304 get ID of current thread
308 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c33"></a><a href=
"#fiber.migration.c32"><img src=
"../../../../../doc/src/images/callouts/5.png" alt=
"5" border=
"0"></a> </p></td>
309 <td valign=
"top" align=
"left"><p>
310 test if fiber was migrated to another thread
314 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c35"></a><a href=
"#fiber.migration.c34"><img src=
"../../../../../doc/src/images/callouts/6.png" alt=
"6" border=
"0"></a> </p></td>
315 <td valign=
"top" align=
"left"><p>
316 Decrement fiber counter for each completed fiber.
320 <td width=
"5%" valign=
"top" align=
"left"><p><a name=
"fiber.migration.c37"></a><a href=
"#fiber.migration.c36"><img src=
"../../../../../doc/src/images/callouts/7.png" alt=
"7" border=
"0"></a> </p></td>
321 <td valign=
"top" align=
"left"><p>
322 Notify all fibers waiting on
<code class=
"computeroutput"><span class=
"identifier">cnd_count
</span></code>.
327 <a name=
"fiber.migration.h3"></a>
328 <span><a name=
"fiber.migration.scheduling_fibers"></a></span><a class=
"link" href=
"migration.html#fiber.migration.scheduling_fibers">Scheduling
332 The fiber scheduler
<code class=
"computeroutput"><span class=
"identifier">shared_ready_queue
</span></code>
333 is like
<code class=
"computeroutput"><span class=
"identifier">round_robin
</span></code>, except
334 that it shares a common ready queue among all participating threads. A thread
335 participates in this pool by executing
<a class=
"link" href=
"fiber_mgmt/fiber.html#use_scheduling_algorithm"><code class=
"computeroutput">use_scheduling_algorithm()
</code></a>
337 any other
<span class=
"bold"><strong>Boost.Fiber
</strong></span> operation.
340 The important point about the ready queue is that it
’s a class static, common
341 to all instances of shared_ready_queue. Fibers that are enqueued via
<a class=
"link" href=
"scheduling.html#algorithm_awakened"><code class=
"computeroutput">algorithm::awakened()
</code></a> (fibers
342 that are ready to be resumed) are thus available to all threads. It is required
343 to reserve a separate, scheduler-specific queue for the thread
’s main fiber
344 and dispatcher fibers: these may
<span class=
"emphasis"><em>not
</em></span> be shared between
345 threads! When we
’re passed either of these fibers, push it there instead of
346 in the shared queue: it would be Bad News for thread B to retrieve and attempt
347 to execute thread A
’s main fiber.
353 When
<a class=
"link" href=
"scheduling.html#algorithm_pick_next"><code class=
"computeroutput">algorithm::pick_next()
</code></a> gets called inside one thread,
354 a fiber is dequeued from
<span class=
"emphasis"><em>rqueue_
</em></span> and will be resumed in
361 The source code above is found in
<a href=
"../../../examples/work_sharing.cpp" target=
"_top">work_sharing.cpp
</a>.
363 <div class=
"footnotes">
364 <br><hr width=
"100" align=
"left">
365 <div class=
"footnote"><p><sup>[
<a name=
"ftn.fiber.migration.f0" href=
"#fiber.migration.f0" class=
"para">2</a>]
</sup>
366 The
<span class=
"quote">“<span class=
"quote">main
</span>”</span> fiber on each thread, that is, the fiber on which
367 the thread is launched, cannot migrate to any other thread. Also
<span class=
"bold"><strong>Boost.Fiber
</strong></span> implicitly creates a dispatcher fiber
368 for each thread
— this cannot migrate either.
370 <div class=
"footnote"><p><sup>[
<a name=
"ftn.fiber.migration.f1" href=
"#fiber.migration.f1" class=
"para">3</a>]
</sup>
371 Of course it would be problematic to migrate a fiber that relies on
<a class=
"link" href=
"overview.html#thread_local_storage">thread-local storage
</a>.
375 <table xmlns:
rev=
"http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width=
"100%"><tr>
376 <td align=
"left"></td>
377 <td align=
"right"><div class=
"copyright-footer">Copyright
© 2013 Oliver Kowalke
<p>
378 Distributed under the Boost Software License, Version
1.0. (See accompanying
379 file LICENSE_1_0.txt or copy at
<a href=
"http://www.boost.org/LICENSE_1_0.txt" target=
"_top">http://www.boost.org/LICENSE_1_0.txt
</a>)
384 <div class=
"spirit-nav">
385 <a accesskey=
"p" href=
"fls.html"><img src=
"../../../../../doc/src/images/prev.png" alt=
"Prev"></a><a accesskey=
"u" href=
"../index.html"><img src=
"../../../../../doc/src/images/up.png" alt=
"Up"></a><a accesskey=
"h" href=
"../index.html"><img src=
"../../../../../doc/src/images/home.png" alt=
"Home"></a><a accesskey=
"n" href=
"callbacks.html"><img src=
"../../../../../doc/src/images/next.png" alt=
"Next"></a>