1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 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.79.1"> 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"> 11</head> 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> 20</tr></table> 21<hr> 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> 24</div> 25<div class="section"> 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 28 between threads</a> 29</h2></div></div></div> 30<h4> 31<a name="fiber.migration.h0"></a> 32 <span class="phrase"><a name="fiber.migration.overview"></a></span><a class="link" href="migration.html#fiber.migration.overview">Overview</a> 33 </h4> 34<p> 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.<a href="#ftn.fiber.migration.f0" class="footnote" name="fiber.migration.f0"><sup class="footnote">[3]</sup></a><sup>,</sup><a href="#ftn.fiber.migration.f1" class="footnote" name="fiber.migration.f1"><sup class="footnote">[4]</sup></a> 38 </p> 39<p> 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. 50 </p> 51<p> 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>. 56 </p> 57<p> 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. 61 </p> 62<p> 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>. 67 </p> 68<p> 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. 73 </p> 74<p> 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>. 81 </p> 82<h4> 83<a name="fiber.migration.h1"></a> 84 <span class="phrase"><a name="fiber.migration.example_of_work_sharing"></a></span><a class="link" href="migration.html#fiber.migration.example_of_work_sharing">Example 85 of work sharing</a> 86 </h4> 87<p> 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>. 96 </p> 97<p> 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. 102 </p> 103<h4> 104<a name="fiber.migration.h2"></a> 105 <span class="phrase"><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> 107 </h4> 108<p> 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 111 launched. 112 </p> 113<p> 114</p> 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> 116 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">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">thread_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_type</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> 136</pre> 137<p> 138 </p> 139<div class="calloutlist"><table border="0" summary="Callout list"> 140<tr> 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 145 pool. 146 </p></td> 147</tr> 148<tr> 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. 154 </p></td> 155</tr> 156<tr> 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. 160 </p></td> 161</tr> 162<tr> 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. 166 </p></td> 167</tr> 168<tr> 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 172 </p></td> 173</tr> 174<tr> 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_type</span></code> is typedef'ed 178 as <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> > 179 </p></td> 180</tr> 181<tr> 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. 186 </p></td> 187</tr> 188<tr> 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). 194 </p></td> 195</tr> 196<tr> 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 200 </p></td> 201</tr> 202</table></div> 203<p> 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. 208 </p> 209<p> 210</p> 211<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">thread</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">detail</span><span class="special">::</span><span class="identifier">thread_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_type</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> 221</pre> 222<p> 223 </p> 224<div class="calloutlist"><table border="0" summary="Callout list"> 225<tr> 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. 230 </p></td> 231</tr> 232<tr> 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 236 </p></td> 237</tr> 238<tr> 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. 243 </p></td> 244</tr> 245</table></div> 246<p> 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. 250 </p> 251<p> 252</p> 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_type</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> 279</pre> 280<p> 281 </p> 282<div class="calloutlist"><table border="0" summary="Callout list"> 283<tr> 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 287 </p></td> 288</tr> 289<tr> 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> 292 loop ten times 293 </p></td> 294</tr> 295<tr> 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 299 </p></td> 300</tr> 301<tr> 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 305 </p></td> 306</tr> 307<tr> 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 311 </p></td> 312</tr> 313<tr> 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. 317 </p></td> 318</tr> 319<tr> 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>. 323 </p></td> 324</tr> 325</table></div> 326<h4> 327<a name="fiber.migration.h3"></a> 328 <span class="phrase"><a name="fiber.migration.scheduling_fibers"></a></span><a class="link" href="migration.html#fiber.migration.scheduling_fibers">Scheduling 329 fibers</a> 330 </h4> 331<p> 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> 336before 337 any other <span class="bold"><strong>Boost.Fiber</strong></span> operation. 338 </p> 339<p> 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. 348 </p> 349<p> 350 [awakened_ws] 351 </p> 352<p> 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 355 that thread. 356 </p> 357<p> 358 [pick_next_ws] 359 </p> 360<p> 361 The source code above is found in <a href="../../../examples/work_sharing.cpp" target="_top">work_sharing.cpp</a>. 362 </p> 363<div class="footnotes"> 364<br><hr style="width:100; text-align:left;margin-left: 0"> 365<div id="ftn.fiber.migration.f0" class="footnote"><p><a href="#fiber.migration.f0" class="para"><sup class="para">[3] </sup></a> 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. 369 </p></div> 370<div id="ftn.fiber.migration.f1" class="footnote"><p><a href="#fiber.migration.f1" class="para"><sup class="para">[4] </sup></a> 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>. 372 </p></div> 373</div> 374</div> 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>) 380 </p> 381</div></td> 382</tr></table> 383<hr> 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> 386</div> 387</body> 388</html> 389