You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
<p>An executor manages a set of worker threads to run one or multiple taskflows using an efficient work-stealing scheduling algorithm.</p><preclass="m-code"><spanclass="c1">// Declare an executor and a taskflow</span>
<spanclass="c1">// Add three tasks into the taskflow</span>
<spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Task</span><spanclass="w"></span><spanclass="n">A</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">taskflow</span><spanclass="p">.</span><spanclass="n">emplace</span><spanclass="p">([]</span><spanclass="w"></span><spanclass="p">()</span><spanclass="w"></span><spanclass="p">{</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"This is TaskA</span><spanclass="se">\n</span><spanclass="s">"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">});</span>
<spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Task</span><spanclass="w"></span><spanclass="n">B</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">taskflow</span><spanclass="p">.</span><spanclass="n">emplace</span><spanclass="p">([]</span><spanclass="w"></span><spanclass="p">()</span><spanclass="w"></span><spanclass="p">{</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"This is TaskB</span><spanclass="se">\n</span><spanclass="s">"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">});</span>
<spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Task</span><spanclass="w"></span><spanclass="n">C</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">taskflow</span><spanclass="p">.</span><spanclass="n">emplace</span><spanclass="p">([]</span><spanclass="w"></span><spanclass="p">()</span><spanclass="w"></span><spanclass="p">{</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"This is TaskC</span><spanclass="se">\n</span><spanclass="s">"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">});</span>
<spanclass="c1">// Build precedence between tasks</span>
<spanclass="n">fu</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// block until the execution completes</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[](){</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"end of 1 run"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">}).</span><spanclass="n">wait</span><spanclass="p">();</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">wait_for_all</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// block until all associated executions finish</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_n</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="mi">4</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[](){</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"end of 4 runs"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">}).</span><spanclass="n">wait</span><spanclass="p">();</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_until</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[</span><spanclass="n">cnt</span><spanclass="o">=</span><spanclass="mi">0</span><spanclass="p">]</span><spanclass="w"></span><spanclass="p">()</span><spanclass="w"></span><spanclass="k">mutable</span><spanclass="w"></span><spanclass="p">{</span><spanclass="w"></span><spanclass="k">return</span><spanclass="w"></span><spanclass="o">++</span><spanclass="n">cnt</span><spanclass="w"></span><spanclass="o">==</span><spanclass="w"></span><spanclass="mi">10</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">});</span></pre><p>All the <code>run</code> methods are <em>thread-safe</em>. You can submit multiple taskflows at the same time to an executor from different threads.</p>
<p>constructs the executor with <code>N</code> worker threads</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">N</td>
<td>number of workers (default <ahref="http://en.cppreference.com/w/cpp/thread/thread/hardware_concurrency.html" class="m-doc-external">std::<wbr/>thread::<wbr/>hardware_concurrency</a>)</td>
</tr>
<tr>
<td>wix</td>
<td>interface class instance to configure workers' behaviors</td>
</tr>
</tbody>
</table>
<p>The constructor spawns <code>N</code> worker threads to run tasks in a work-stealing loop. The number of workers must be greater than zero or an exception will be thrown. By default, the number of worker threads is equal to the maximum hardware concurrency returned by <ahref="http://en.cppreference.com/w/cpp/thread/thread/hardware_concurrency.html" class="m-doc-external">std::<wbr/>thread::<wbr/>hardware_concurrency</a>.</p><p>Users can alter the worker behavior, such as changing thread affinity, via deriving an instance from <ahref="classtf_1_1WorkerInterface.html" class="m-doc">tf::<wbr/>WorkerInterface</a>.</p>
<p>The destructor calls <ahref="#ab9aa252f70e9a40020a1e5a89d485b85" class="m-doc">Executor::<wbr/>wait_for_all</a> to wait for all submitted taskflows to complete and then notifies all worker threads to stop and join these threads.</p>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow once and returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">);</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a> object</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow once and returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution. The executor will take care of the lifetime of the moved taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">move</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">));</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<td>a callable object to be invoked after this run</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow once and invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[](){</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"done"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">});</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<p>runs a moved taskflow once and invoke a callback upon completion</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">taskflow</td>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a> object</td>
</tr>
<tr>
<td>callable</td>
<td>a callable object to be invoked after this run</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow once and invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution. The executor will take care of the lifetime of the moved taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow <code>N</code> times and returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_n</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="mi">2</span><spanclass="p">);</span><spanclass="w"></span><spanclass="c1">// run taskflow 2 times</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<p>runs a moved taskflow for <code>N</code> times</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">taskflow</td>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a> object</td>
</tr>
<tr>
<td>N</td>
<td>number of runs</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow <code>N</code> times and returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution. The executor will take care of the lifetime of the moved taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_n</span><spanclass="p">(</span>
<spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">move</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">),</span><spanclass="w"></span><spanclass="mi">2</span><spanclass="w"></span><spanclass="c1">// run the moved taskflow 2 times</span>
<spanclass="p">);</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<td>a callable object to be invoked after this run</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow <code>N</code> times and invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span>
<spanclass="w"></span><spanclass="n">taskflow</span><spanclass="p">,</span><spanclass="w"></span><spanclass="mi">2</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[](){</span><spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"done"</span><spanclass="p">;</span><spanclass="w"></span><spanclass="p">}</span><spanclass="w"></span><spanclass="c1">// runs taskflow 2 times and invoke</span>
<spanclass="w"></span><spanclass="c1">// the lambda to print "done"</span>
<spanclass="p">);</span>
<spanclass="c1">// do something else</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<p>runs a moved taskflow for <code>N</code> times and then invokes a callback</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">taskflow</td>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a></td>
</tr>
<tr>
<td>N</td>
<td>number of runs</td>
</tr>
<tr>
<td>callable</td>
<td>a callable object to be invoked after this run</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow <code>N</code> times and invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_n</span><spanclass="p">(</span>
<spanclass="w"></span><spanclass="c1">// run the moved taskflow 2 times and invoke the lambda to print "done"</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<td>a boolean predicate to return <code>true</code> for stop</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow multiple times until the predicate returns <code>true</code>. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_until</span><spanclass="p">(</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<p>runs a moved taskflow and keeps running it until the predicate becomes true</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">taskflow</td>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a> object</td>
</tr>
<tr>
<td>pred</td>
<td>a boolean predicate to return <code>true</code> for stop</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow multiple times until the predicate returns <code>true</code>. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution. The executor will take care of the lifetime of the moved taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_until</span><spanclass="p">(</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<td>a boolean predicate to return <code>true</code> for stop</td>
</tr>
<tr>
<td>callable</td>
<td>a callable object to be invoked after this run completes</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes the given taskflow multiple times until the predicate returns <code>true</code> and then invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_until</span><spanclass="p">(</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>The executor does not own the given taskflow. It is your responsibility to ensure the taskflow remains alive during its execution.</p></aside>
<p>runs a moved taskflow and keeps running it until the predicate becomes true and then invokes the callback</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">taskflow</td>
<td>a moved <ahref="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr/>Taskflow</a></td>
</tr>
<tr>
<td>pred</td>
<td>a boolean predicate to return <code>true</code> for stop</td>
</tr>
<tr>
<td>callable</td>
<td>a callable object to be invoked after this run completes</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> that holds the result of the execution</td>
</tr>
</tfoot>
</table>
<p>This member function executes a moved taskflow multiple times until the predicate returns <code>true</code> and then invokes the given callable when the execution completes. This member function returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that eventually holds the result of the execution. The executor will take care of the lifetime of the moved taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Future</span><spanclass="o"><</span><spanclass="kt">void</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run_until</span><spanclass="p">(</span>
<spanclass="n">future</span><spanclass="p">.</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>This member function is thread-safe.</p>
<p>runs a target graph and waits until it completes using an internal worker of this executor</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">T</td>
<td>target type which has <code><ahref="classtf_1_1Graph.html" class="m-doc">tf::<wbr/>Graph</a>& T::graph()</code> defined</td>
</tr>
</tbody>
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>target</td>
<td>the target task graph object</td>
</tr>
</tbody>
</table>
<p>The method runs a target graph which has <code><ahref="classtf_1_1Graph.html" class="m-doc">tf::<wbr/>Graph</a>& T::graph()</code> defined and waits until the execution completes. Unlike the typical flow of calling <code><ahref="#a519777f5783981d534e9e53b99712069" class="m-doc">tf::<wbr/>Executor::<wbr/>run</a></code> series plus waiting on the result, this method must be called by an internal worker of this executor. The caller worker will participate in the work-stealing loop of the scheduler, thereby avoiding potential deadlock caused by blocked waiting.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="nf">executor</span><spanclass="p">(</span><spanclass="mi">2</span><spanclass="p">);</span>
<spanclass="w"></span><spanclass="c1">//executor.run(tf).wait(); <- blocking the worker without doing anything</span>
<spanclass="w"></span><spanclass="c1">// will introduce deadlock</span>
<spanclass="w"></span><spanclass="p">});</span>
<spanclass="p">}</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">).</span><spanclass="n">wait</span><spanclass="p">();</span></pre><p>The method is thread-safe as long as the target is not concurrently ran by two or more threads.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>You must call <ahref="#a8fcd9e0557922bb8194999f0cd433ea8" class="m-doc">tf::<wbr/>Executor::<wbr/>corun</a> from a worker of the calling executor or an exception will be thrown.</p></aside>
<p>keeps running the work-stealing loop until the predicate becomes true</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">P</td>
<td>predicate type</td>
</tr>
</tbody>
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>predicate</td>
<td>a boolean predicate to indicate when to stop the loop</td>
</tr>
</tbody>
</table>
<p>The method keeps the caller worker running in the work-stealing loop until the stop predicate becomes true.</p><preclass="m-code"><spanclass="n">taskflow</span><spanclass="p">.</span><spanclass="n">emplace</span><spanclass="p">([</span><spanclass="o">&</span><spanclass="p">](){</span>
<spanclass="p">});</span></pre><asideclass="m-note m-warning"><h4>Attention</h4><p>You must call <ahref="#a0fc6eb19f168dc4a9cd0a7c6187c1d2d" class="m-doc">tf::<wbr/>Executor::<wbr/>corun_until</a> from a worker of the calling executor or an exception will be thrown.</p></aside>
<p>This member function waits until all submitted tasks (e.g., taskflows, asynchronous tasks) to finish.</p><preclass="m-code"><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow1</span><spanclass="p">);</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">wait_for_all</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// wait until the above submitted taskflows finish</span></pre>
<p>Each worker represents one unique thread spawned by an executor upon its construction time.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="nf">executor</span><spanclass="p">(</span><spanclass="mi">4</span><spanclass="p">);</span>
<p>queries the number of running topologies at the time of this call</p>
<p>When a taskflow is submitted to an executor, a topology is created to store runtime metadata of the running taskflow. When the execution of the submitted taskflow finishes, its corresponding topology will be removed from the executor.</p><preclass="m-code"><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">run</span><spanclass="p">(</span><spanclass="n">taskflow</span><spanclass="p">);</span>
<spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">num_topologies</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// 0 or 1 (taskflow still running)</span></pre>
<spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">num_taskflows</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// 0 or 1 (taskflow still running)</span></pre>
<p>queries the id of the caller thread within this executor</p>
<p>Each worker has an unique id in the range of <code>0</code> to <code>N-1</code> associated with its parent executor. If the caller thread does not belong to the executor, <code>-1</code> is returned.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="nf">executor</span><spanclass="p">(</span><spanclass="mi">4</span><spanclass="p">);</span><spanclass="w"></span><spanclass="c1">// 4 workers in the executor</span>
<spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">this_worker_id</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// -1 (main thread is not a worker)</span>
<p>constructs an observer to inspect the activities of worker threads</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">Observer</td>
<td>observer type derived from <ahref="classtf_1_1ObserverInterface.html" class="m-doc">tf::<wbr/>ObserverInterface</a></td>
</tr>
<tr>
<td>ArgsT</td>
<td>argument parameter pack</td>
</tr>
</tbody>
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>args</td>
<td>arguments to forward to the constructor of the observer</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a shared pointer to the created observer</td>
</tr>
</tfoot>
</table>
<p>Each executor manages a list of observers with shared ownership with callers. For each of these observers, the two member functions, <ahref="classtf_1_1ObserverInterface.html#a8225fcacb03089677a1efc4b16b734cc" class="m-doc">tf::<wbr/>ObserverInterface::<wbr/>on_entry</a> and <ahref="classtf_1_1ObserverInterface.html#aa22f5378154653f08d9a58326bda4754" class="m-doc">tf::<wbr/>ObserverInterface::<wbr/>on_exit</a> will be called before and after the execution of a task.</p><p>This member function is not thread-safe.</p>
<p>creates a parameterized asynchronous task to run the given function</p>
<tableclass="m-table m-fullwidth m-flat">
<thead>
<tr><thcolspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<tdstyle="width: 1%">P</td>
<td>task parameter type</td>
</tr>
<tr>
<td>F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><thcolspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>params</td>
<td>task parameters</td>
</tr>
<tr>
<td>func</td>
<td>callable object</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Returns</th>
<td>a <ahref="https://en.cppreference.com/w/cpp/thread/future">std::<wbr/>future</a> that will hold the result of the execution</td>
</tr>
</tfoot>
</table>
<p>The method creates a parameterized asynchronous task to run the given function and return a <ahref="https://en.cppreference.com/w/cpp/thread/future">std::<wbr/>future</a> object that eventually will hold the result of the execution.</p><preclass="m-code"><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">future</span><spanclass="o"><</span><spanclass="kt">int</span><spanclass="o">></span><spanclass="w"></span><spanclass="n">future</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">.</span><spanclass="n">async</span><spanclass="p">(</span><spanclass="s">"name"</span><spanclass="p">,</span><spanclass="w"></span><spanclass="p">[](){</span>
<spanclass="w"></span><spanclass="n">std</span><spanclass="o">::</span><spanclass="n">cout</span><spanclass="w"></span><spanclass="o"><<</span><spanclass="w"></span><spanclass="s">"create an asynchronous task with a name and returns 1</span><spanclass="se">\n</span><spanclass="s">"</span><spanclass="p">;</span>