mesytec-mnode/external/taskflow-3.8.0/docs/classtf_1_1Runtime.html
2025-01-04 01:25:05 +01:00

796 lines
73 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>tf::Runtime class | Taskflow QuickStart</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
<link rel="stylesheet" href="m-dark+documentation.compiled.css" />
<link rel="icon" href="favicon.ico" type="image/vnd.microsoft.icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#22272e" />
</head>
<body>
<header><nav id="navigation">
<div class="m-container">
<div class="m-row">
<span id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">
<a href="https://taskflow.github.io"><img src="taskflow_logo.png" alt="" />Taskflow</a> <span class="m-breadcrumb">|</span> <a href="index.html" class="m-thin">QuickStart</a>
</span>
<div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
<a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
<path id="m-doc-search-icon-path" d="m6 0c-3.31 0-6 2.69-6 6 0 3.31 2.69 6 6 6 1.49 0 2.85-0.541 3.89-1.44-0.0164 0.338 0.147 0.759 0.5 1.15l3.22 3.79c0.552 0.614 1.45 0.665 2 0.115 0.55-0.55 0.499-1.45-0.115-2l-3.79-3.22c-0.392-0.353-0.812-0.515-1.15-0.5 0.895-1.05 1.44-2.41 1.44-3.89 0-3.31-2.69-6-6-6zm0 1.56a4.44 4.44 0 0 1 4.44 4.44 4.44 4.44 0 0 1-4.44 4.44 4.44 4.44 0 0 1-4.44-4.44 4.44 4.44 0 0 1 4.44-4.44z"/>
</svg></a>
<a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
<a id="m-navbar-hide" href="#" title="Hide navigation"></a>
</div>
<div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
<div class="m-row">
<ol class="m-col-t-6 m-col-m-none">
<li><a href="pages.html">Handbook</a></li>
<li><a href="namespaces.html">Namespaces</a></li>
</ol>
<ol class="m-col-t-6 m-col-m-none" start="3">
<li><a href="annotated.html">Classes</a></li>
<li><a href="files.html">Files</a></li>
<li class="m-show-m"><a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
<use href="#m-doc-search-icon-path" />
</svg></a></li>
</ol>
</div>
</div>
</div>
</div>
</nav></header>
<main><article>
<div class="m-container m-container-inflatable">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<h1>
<span class="m-breadcrumb"><a href="namespacetf.html">tf</a>::<wbr/></span>Runtime <span class="m-thin">class</span>
<div class="m-doc-include m-code m-inverted m-text-right"><span class="cp">#include</span> <a class="cpf" href="graph_8hpp.html">&lt;taskflow/core/graph.hpp&gt;</a></div>
</h1>
<p>class to include a runtime object in a task</p>
<nav class="m-block m-default">
<h3>Contents</h3>
<ul>
<li>
Reference
<ul>
<li><a href="#derived-classes">Derived classes</a></li>
<li><a href="#typeless-methods">Constructors, destructors, conversion operators</a></li>
<li><a href="#pub-methods">Public functions</a></li>
</ul>
</li>
</ul>
</nav>
<p>A runtime object allows users to interact with the scheduling runtime inside a task, such as scheduling an active task, spawning a subflow, and so on.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">(</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">C</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// C must be captured by reference</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">schedule</span><span class="p">(</span><span class="n">C</span><span class="p">);</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;C</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;D</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>
<span class="p">);</span>
<span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">);</span>
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>A runtime object is associated with the worker and the executor that runs the task.</p>
<section id="derived-classes">
<h2><a href="#derived-classes">Derived classes</a></h2>
<dl class="m-doc">
<dt>
class <a href="classtf_1_1Subflow.html" class="m-doc">Subflow</a>
</dt>
<dd>class to construct a subflow graph from the execution of a dynamic task</dd>
</dl>
</section>
<section id="typeless-methods">
<h2><a href="#typeless-methods">Constructors, destructors, conversion operators</a></h2>
<dl class="m-doc">
<dt>
<span class="m-doc-wrap-bumper"><a href="#a7bf472d4afca4eed0f1a0fe4168c1097" class="m-doc">~Runtime</a>(</span><span class="m-doc-wrap">)</span>
</dt>
<dd>destroys the runtime object</dd>
</dl>
</section>
<section id="pub-methods">
<h2><a href="#pub-methods">Public functions</a></h2>
<dl class="m-doc">
<dt>
<span class="m-doc-wrap-bumper">auto <a href="#a4ee48a82df1f9758a999d18e6015cec4" class="m-doc">executor</a>(</span><span class="m-doc-wrap">) -&gt; <a href="classtf_1_1Executor.html" class="m-doc">Executor</a>&amp;</span>
</dt>
<dd>obtains the running executor</dd>
<dt id="ae1dbce75fd7375ae3bf38948638e34ec">
<span class="m-doc-wrap-bumper">auto <a href="#ae1dbce75fd7375ae3bf38948638e34ec" class="m-doc-self">worker</a>(</span><span class="m-doc-wrap">) -&gt; <a href="classtf_1_1Worker.html" class="m-doc">Worker</a>&amp;</span>
</dt>
<dd>acquire a reference to the underlying worker</dd>
<dt>
<span class="m-doc-wrap-bumper">void <a href="#aa7e72cc0f298475195b252c8f1793343" class="m-doc">schedule</a>(</span><span class="m-doc-wrap"><a href="classtf_1_1Task.html" class="m-doc">Task</a> task)</span>
</dt>
<dd>schedules an active task immediately to the worker&#x27;s queue</dd>
<dt>
<div class="m-doc-template">template&lt;typename F&gt;</div>
<span class="m-doc-wrap-bumper">auto <a href="#a5688b13034f179c4a8b2b0ebbb215051" class="m-doc">async</a>(</span><span class="m-doc-wrap">F&amp;&amp; f) -&gt; auto</span>
</dt>
<dd>runs the given callable asynchronously</dd>
<dt>
<div class="m-doc-template">template&lt;typename P, typename F&gt;</div>
<span class="m-doc-wrap-bumper">auto <a href="#a333a76d63e50f3ddfbea60c4356b86f3" class="m-doc">async</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f) -&gt; auto</span>
</dt>
<dd>runs the given callable asynchronously</dd>
<dt>
<div class="m-doc-template">template&lt;typename F&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">silent_async</a>(</span><span class="m-doc-wrap">F&amp;&amp; f)</span>
</dt>
<dd>runs the given function asynchronously without returning any future object</dd>
<dt>
<div class="m-doc-template">template&lt;typename P, typename F&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#a532d8cd09ebee59023e3ad65f3220f4e" class="m-doc">silent_async</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f)</span>
</dt>
<dd>runs the given function asynchronously without returning any future object</dd>
<dt>
<div class="m-doc-template">template&lt;typename F&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#ab32a718db1cc32d997b68b4f8482fc7e" class="m-doc">silent_async_unchecked</a>(</span><span class="m-doc-wrap">F&amp;&amp; f)</span>
</dt>
<dd>similar to <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">tf::<wbr />Runtime::<wbr />silent_async</a> but the caller must be the worker of the runtime</dd>
<dt>
<div class="m-doc-template">template&lt;typename P, typename F&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#ae5144f53fe3a52e7d57de9e01815c814" class="m-doc">silent_async_unchecked</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f)</span>
</dt>
<dd>similar to <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">tf::<wbr />Runtime::<wbr />silent_async</a> but the caller must be the worker of the runtime</dd>
<dt>
<div class="m-doc-template">template&lt;typename T&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#a1c772e90614302024cfa52fa86d75cac" class="m-doc">corun</a>(</span><span class="m-doc-wrap">T&amp;&amp; target)</span>
</dt>
<dd>co-runs the given target and waits until it completes</dd>
<dt>
<div class="m-doc-template">template&lt;typename P&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#a078fc4e7202426221d45e44b08ad60e6" class="m-doc">corun_until</a>(</span><span class="m-doc-wrap">P&amp;&amp; predicate)</span>
</dt>
<dd>keeps running the work-stealing loop until the predicate becomes true</dd>
<dt>
<span class="m-doc-wrap-bumper">void <a href="#afcc18484a95fd2a834940d878eaf4dfc" class="m-doc">corun_all</a>(</span><span class="m-doc-wrap">)</span>
</dt>
<dd>corun all asynchronous tasks spawned by this runtime with other workers</dd>
<dt>
<div class="m-doc-template">template&lt;typename... S, std::enable_if_t&lt;all_same_v&lt;<a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>, std::decay_t&lt;S&gt;...&gt;, void&gt;* = nullptr&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#ada6b02ea097968de011bb3825a7ec48b" class="m-doc">acquire</a>(</span><span class="m-doc-wrap">S &amp;&amp; ... semaphores)</span>
</dt>
<dd>acquires the given semaphores with a deadlock avoidance algorithm</dd>
<dt>
<div class="m-doc-template">template&lt;typename I, std::enable_if_t&lt;std::is_same_v&lt;deref_t&lt;I&gt;, <a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>&gt;, void&gt;* = nullptr&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#aee253a907d8ade4e3162f1b2ea8a97cf" class="m-doc">acquire</a>(</span><span class="m-doc-wrap">I first,
I last)</span>
</dt>
<dd>acquires the given range of semaphores with a deadlock avoidance algorithm</dd>
<dt>
<div class="m-doc-template">template&lt;typename... S, std::enable_if_t&lt;all_same_v&lt;<a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>, std::decay_t&lt;S&gt;...&gt;, void&gt;* = nullptr&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#acc36e4d62a17e19e07f0c82a4c5f1d95" class="m-doc">release</a>(</span><span class="m-doc-wrap">S &amp;&amp; ... semaphores)</span>
</dt>
<dd>releases the given semaphores</dd>
<dt>
<div class="m-doc-template">template&lt;typename I, std::enable_if_t&lt;std::is_same_v&lt;deref_t&lt;I&gt;, <a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>&gt;, void&gt;* = nullptr&gt;</div>
<span class="m-doc-wrap-bumper">void <a href="#a83ebb3537650dd6e7ea32a60ece8462c" class="m-doc">release</a>(</span><span class="m-doc-wrap">I first,
I last)</span>
</dt>
<dd>releases the given range of semaphores</dd>
</dl>
</section>
<section>
<h2>Function documentation</h2>
<section class="m-doc-details" id="a7bf472d4afca4eed0f1a0fe4168c1097"><div>
<h3>
<span class="m-doc-wrap-bumper"> tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a7bf472d4afca4eed0f1a0fe4168c1097" class="m-doc-self">~Runtime</a>(</span><span class="m-doc-wrap">)</span></span>
</h3>
<p>destroys the runtime object</p>
<p>Issues a <a href="#afcc18484a95fd2a834940d878eaf4dfc" class="m-doc">tf::<wbr />Runtime::<wbr />corun_all</a> to finish all spawned asynchronous tasks and then destroys the runtime object.</p>
</div></section>
<section class="m-doc-details" id="a4ee48a82df1f9758a999d18e6015cec4"><div>
<h3>
<span class="m-doc-wrap-bumper"><a href="classtf_1_1Executor.html" class="m-doc">Executor</a>&amp; tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a4ee48a82df1f9758a999d18e6015cec4" class="m-doc-self">executor</a>(</span><span class="m-doc-wrap">)</span></span>
</h3>
<p>obtains the running executor</p>
<p>The running executor of a runtime task is the executor that runs the parent taskflow of that runtime task.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">rt</span><span class="p">.</span><span class="n">executor</span><span class="p">())</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">&amp;</span><span class="n">executor</span><span class="p">);</span>
<span class="p">});</span>
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre>
</div></section>
<section class="m-doc-details" id="aa7e72cc0f298475195b252c8f1793343"><div>
<h3>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#aa7e72cc0f298475195b252c8f1793343" class="m-doc-self">schedule</a>(</span><span class="m-doc-wrap"><a href="classtf_1_1Task.html" class="m-doc">Task</a> task)</span></span>
</h3>
<p>schedules an active task immediately to the worker&#x27;s queue</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">task</td>
<td>the given active task to schedule immediately</td>
</tr>
</tbody>
</table>
<p>This member function immediately schedules an active task to the task queue of the associated worker in the runtime task. An active task is a task in a running taskflow. The task may or may not be running, and scheduling that task will immediately put the task into the task queue of the worker that is running the runtime task. Consider the following example:</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">(</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">C</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// C must be captured by reference</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">schedule</span><span class="p">(</span><span class="n">C</span><span class="p">);</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;C</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;D</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>
<span class="p">);</span>
<span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">);</span>
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>The executor will first run the condition task <code>A</code> which returns <code>0</code> to inform the scheduler to go to the runtime task <code>B</code>. During the execution of <code>B</code>, it directly schedules task <code>C</code> without going through the normal taskflow graph scheduling process. At this moment, task <code>C</code> is active because its parent taskflow is running. When the taskflow finishes, we will see both <code>B</code> and <code>C</code> in the output.</p>
</div></section>
<section class="m-doc-details" id="a5688b13034f179c4a8b2b0ebbb215051"><div>
<h3>
<div class="m-doc-template">
template&lt;typename F&gt;
</div>
<span class="m-doc-wrap-bumper">auto tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a5688b13034f179c4a8b2b0ebbb215051" class="m-doc-self">async</a>(</span><span class="m-doc-wrap">F&amp;&amp; f)</span></span>
</h3>
<p>runs the given callable asynchronously</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>f</td>
<td>callable object</td>
</tr>
</tbody>
</table>
<p>The method creates an asynchronous task to launch the given function on the given arguments. The difference to <a href="classtf_1_1Executor.html#af960048056f7c6b5bc71f4f526f05df7" class="m-doc">tf::<wbr />Executor::<wbr />async</a> is that the created asynchronous task pertains to the runtime object. Applications can explicitly issue <a href="#afcc18484a95fd2a834940d878eaf4dfc" class="m-doc">tf::<wbr />Runtime::<wbr />corun_all</a> to wait for all spawned asynchronous tasks to finish. For example:</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">counter</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">fu1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">fu2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="n">fu1</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
<span class="w"> </span><span class="n">fu2</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// spawn 100 asynchronous tasks from the worker of the runtime</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// wait for the 100 asynchronous tasks to finish</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">102</span><span class="p">);</span>
<span class="p">});</span></pre><p>This method is thread-safe and can be called by multiple workers that hold the reference to the runtime. For example, the code below spawns 100 tasks from the worker of a runtime, and each of the 100 tasks spawns another task that will be run by another worker.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">counter</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="c1">// worker of the runtime spawns 100 tasks each spawning another task</span>
<span class="w"> </span><span class="c1">// that will be run by another worker</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span>
<span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">([](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// wait for the 200 asynchronous tasks to finish</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">200</span><span class="p">);</span>
<span class="p">});</span></pre>
</div></section>
<section class="m-doc-details" id="a333a76d63e50f3ddfbea60c4356b86f3"><div>
<h3>
<div class="m-doc-template">
template&lt;typename P, typename F&gt;
</div>
<span class="m-doc-wrap-bumper">auto tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a333a76d63e50f3ddfbea60c4356b86f3" class="m-doc-self">async</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f)</span></span>
</h3>
<p>runs the given callable asynchronously</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">P</td>
<td>task parameters type</td>
</tr>
<tr>
<td>F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>params</td>
<td>task parameters</td>
</tr>
<tr>
<td>f</td>
<td>callable</td>
</tr>
</tbody>
</table>
<pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">future</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">async</span><span class="p">(</span><span class="s">&quot;my task&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">[](){});</span>
<span class="w"> </span><span class="n">future</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
<span class="p">});</span></pre>
</div></section>
<section class="m-doc-details" id="a0ce29efa2106c8c5a1432e4a55ab2e05"><div>
<h3>
<div class="m-doc-template">
template&lt;typename F&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc-self">silent_async</a>(</span><span class="m-doc-wrap">F&amp;&amp; f)</span></span>
</h3>
<p>runs the given function asynchronously without returning any future object</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>f</td>
<td>callable</td>
</tr>
</tbody>
</table>
<p>This member function is more efficient than <a href="#a5688b13034f179c4a8b2b0ebbb215051" class="m-doc">tf::<wbr />Runtime::<wbr />async</a> and is encouraged to use when there is no data returned.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">counter</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">100</span><span class="p">);</span>
<span class="p">});</span></pre><p>This member function is thread-safe.</p>
</div></section>
<section class="m-doc-details" id="a532d8cd09ebee59023e3ad65f3220f4e"><div>
<h3>
<div class="m-doc-template">
template&lt;typename P, typename F&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a532d8cd09ebee59023e3ad65f3220f4e" class="m-doc-self">silent_async</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f)</span></span>
</h3>
<p>runs the given function asynchronously without returning any future object</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">P</td>
<td></td>
</tr>
<tr>
<td>F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>params</td>
<td>task parameters</td>
</tr>
<tr>
<td>f</td>
<td>callable</td>
</tr>
</tbody>
</table>
<pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async</span><span class="p">(</span><span class="s">&quot;my task&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">[](){});</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="p">});</span></pre>
</div></section>
<section class="m-doc-details" id="ab32a718db1cc32d997b68b4f8482fc7e"><div>
<h3>
<div class="m-doc-template">
template&lt;typename F&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#ab32a718db1cc32d997b68b4f8482fc7e" class="m-doc-self">silent_async_unchecked</a>(</span><span class="m-doc-wrap">F&amp;&amp; f)</span></span>
</h3>
<p>similar to <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">tf::<wbr />Runtime::<wbr />silent_async</a> but the caller must be the worker of the runtime</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>f</td>
<td>callable</td>
</tr>
</tbody>
</table>
<p>The method bypass the check of the caller worker from the executor and thus can only called by the worker of this runtime.</p><pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="c1">// running by the worker of this runtime</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async_unchecked</span><span class="p">([](){});</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="p">});</span></pre>
</div></section>
<section class="m-doc-details" id="ae5144f53fe3a52e7d57de9e01815c814"><div>
<h3>
<div class="m-doc-template">
template&lt;typename P, typename F&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#ae5144f53fe3a52e7d57de9e01815c814" class="m-doc-self">silent_async_unchecked</a>(</span><span class="m-doc-wrap">P&amp;&amp; params,
F&amp;&amp; f)</span></span>
</h3>
<p>similar to <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">tf::<wbr />Runtime::<wbr />silent_async</a> but the caller must be the worker of the runtime</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">P</td>
<td>task parameters type</td>
</tr>
<tr>
<td>F</td>
<td>callable type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>params</td>
<td>task parameters</td>
</tr>
<tr>
<td>f</td>
<td>callable</td>
</tr>
</tbody>
</table>
<p>The method bypass the check of the caller worker from the executor and thus can only called by the worker of this runtime.</p><pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="c1">// running by the worker of this runtime</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async_unchecked</span><span class="p">(</span><span class="s">&quot;my task&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">[](){});</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="p">});</span></pre>
</div></section>
<section class="m-doc-details" id="a1c772e90614302024cfa52fa86d75cac"><div>
<h3>
<div class="m-doc-template">
template&lt;typename T&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a1c772e90614302024cfa52fa86d75cac" class="m-doc-self">corun</a>(</span><span class="m-doc-wrap">T&amp;&amp; target)</span></span>
</h3>
<p>co-runs the given target and waits until it completes</p>
<p>A target can be one of the following forms:</p><ul><li>a subflow task to spawn a subflow or</li><li>a composable graph object with <code><a href="classtf_1_1Graph.html" class="m-doc">tf::<wbr />Graph</a>&amp; T::graph()</code> defined</li></ul><pre class="m-code"><span class="c1">// co-run a subflow and wait until all tasks complete</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun</span><span class="p">([](</span><span class="n">tf</span><span class="o">::</span><span class="n">Subflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">sf</span><span class="p">){</span>
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sf</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){});</span>
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sf</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){});</span>
<span class="w"> </span><span class="p">});</span><span class="w"> </span>
<span class="p">});</span>
<span class="c1">// co-run a taskflow and wait until all tasks complete</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow1</span><span class="p">,</span><span class="w"> </span><span class="n">taskflow2</span><span class="p">;</span>
<span class="n">taskflow1</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;running taskflow1</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="n">taskflow2</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;running taskflow2</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun</span><span class="p">(</span><span class="n">taskflow1</span><span class="p">);</span>
<span class="p">});</span>
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow2</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>Although <a href="#a1c772e90614302024cfa52fa86d75cac" class="m-doc">tf::<wbr />Runtime::<wbr />corun</a> blocks until the operation completes, the caller thread (worker) is not blocked (e.g., sleeping or holding any lock). Instead, the caller thread joins the work-stealing loop of the executor and returns when all tasks in the target completes.</p><aside class="m-note m-warning"><h4>Attention</h4><p>Only the worker of this <a href="classtf_1_1Runtime.html" class="m-doc">tf::<wbr />Runtime</a> can issue corun.</p></aside>
</div></section>
<section class="m-doc-details" id="a078fc4e7202426221d45e44b08ad60e6"><div>
<h3>
<div class="m-doc-template">
template&lt;typename P&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a078fc4e7202426221d45e44b08ad60e6" class="m-doc-self">corun_until</a>(</span><span class="m-doc-wrap">P&amp;&amp; predicate)</span></span>
</h3>
<p>keeps running the work-stealing loop until the predicate becomes true</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">P</td>
<td>predicate type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="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><aside class="m-note m-warning"><h4>Attention</h4><p>Only the worker of this <a href="classtf_1_1Runtime.html" class="m-doc">tf::<wbr />Runtime</a> can issue corun.</p></aside>
</div></section>
<section class="m-doc-details" id="afcc18484a95fd2a834940d878eaf4dfc"><div>
<h3>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#afcc18484a95fd2a834940d878eaf4dfc" class="m-doc-self">corun_all</a>(</span><span class="m-doc-wrap">)</span></span>
</h3>
<p>corun all asynchronous tasks spawned by this runtime with other workers</p>
<p>Coruns all asynchronous tasks (<a href="#a5688b13034f179c4a8b2b0ebbb215051" class="m-doc">tf::<wbr />Runtime::<wbr />async</a>, <a href="#a0ce29efa2106c8c5a1432e4a55ab2e05" class="m-doc">tf::<wbr />Runtime::<wbr />silent_async</a>) with other workers until all those asynchronous tasks finish.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="kt">size_t</span><span class="o">&gt;</span><span class="w"> </span><span class="n">counter</span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="c1">// spawn 100 async tasks and wait</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">100</span><span class="p">);</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// spawn another 100 async tasks and wait</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">silent_async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](){</span><span class="w"> </span><span class="n">counter</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">corun_all</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">counter</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">200</span><span class="p">);</span>
<span class="p">});</span></pre><aside class="m-note m-warning"><h4>Attention</h4><p>Only the worker of this <a href="classtf_1_1Runtime.html" class="m-doc">tf::<wbr />Runtime</a> can issue <a href="#afcc18484a95fd2a834940d878eaf4dfc" class="m-doc">tf::<wbr />Runtime::<wbr />corun_all</a>.</p></aside>
</div></section>
<section class="m-doc-details" id="ada6b02ea097968de011bb3825a7ec48b"><div>
<h3>
<div class="m-doc-template">
template&lt;typename... S, std::enable_if_t&lt;all_same_v&lt;<a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>, std::decay_t&lt;S&gt;...&gt;, void&gt;* = nullptr&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#ada6b02ea097968de011bb3825a7ec48b" class="m-doc-self">acquire</a>(</span><span class="m-doc-wrap">S &amp;&amp; ... semaphores)</span></span>
</h3>
<p>acquires the given semaphores with a deadlock avoidance algorithm</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">S</td>
<td>semaphore type (<a href="classtf_1_1Semaphore.html" class="m-doc">tf::<wbr />Semaphore</a>)</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>semaphores</td>
<td>semaphores</td>
</tr>
</tbody>
</table>
<p>Coruns this worker until acquiring all the semaphores.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Semaphore</span><span class="w"> </span><span class="nf">semaphore</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="c1">// only one worker will enter the &quot;critical_section&quot; at any time</span>
<span class="k">for</span><span class="p">(</span><span class="kt">size_t</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">acquire</span><span class="p">(</span><span class="n">semaphore</span><span class="p">);</span>
<span class="w"> </span><span class="n">critical_section</span><span class="p">();</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">release</span><span class="p">(</span><span class="n">semaphore</span><span class="p">);</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">}</span></pre>
</div></section>
<section class="m-doc-details" id="aee253a907d8ade4e3162f1b2ea8a97cf"><div>
<h3>
<div class="m-doc-template">
template&lt;typename I, std::enable_if_t&lt;std::is_same_v&lt;deref_t&lt;I&gt;, <a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>&gt;, void&gt;* = nullptr&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#aee253a907d8ade4e3162f1b2ea8a97cf" class="m-doc-self">acquire</a>(</span><span class="m-doc-wrap">I first,
I last)</span></span>
</h3>
<p>acquires the given range of semaphores with a deadlock avoidance algorithm</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">I</td>
<td>iterator type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>first</td>
<td>iterator to the beginning (inclusive)</td>
</tr>
<tr>
<td>last</td>
<td>iterator to the end (exclusive)</td>
</tr>
</tbody>
</table>
<p>Coruns this worker until acquiring all the semaphores.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">tf</span><span class="o">::</span><span class="n">Semaphore</span><span class="o">&gt;</span><span class="w"> </span><span class="n">semaphores</span><span class="p">;</span>
<span class="n">semaphores</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="n">semaphores</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="k">auto</span><span class="w"> </span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">semaphores</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
<span class="k">auto</span><span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">semaphores</span><span class="p">.</span><span class="n">end</span><span class="p">();</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="c1">// only one worker will enter the &quot;critical_section&quot; at any time</span>
<span class="k">for</span><span class="p">(</span><span class="kt">size_t</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">acquire</span><span class="p">(</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">);</span>
<span class="w"> </span><span class="n">critical_section</span><span class="p">();</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">release</span><span class="p">(</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">);</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">}</span></pre>
</div></section>
<section class="m-doc-details" id="acc36e4d62a17e19e07f0c82a4c5f1d95"><div>
<h3>
<div class="m-doc-template">
template&lt;typename... S, std::enable_if_t&lt;all_same_v&lt;<a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>, std::decay_t&lt;S&gt;...&gt;, void&gt;* = nullptr&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#acc36e4d62a17e19e07f0c82a4c5f1d95" class="m-doc-self">release</a>(</span><span class="m-doc-wrap">S &amp;&amp; ... semaphores)</span></span>
</h3>
<p>releases the given semaphores</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">S</td>
<td>semaphore type (<a href="classtf_1_1Semaphore.html" class="m-doc">tf::<wbr />Semaphore</a>)</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>semaphores</td>
<td>semaphores</td>
</tr>
</tbody>
</table>
<p>Releases the given semaphores.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Semaphore</span><span class="w"> </span><span class="nf">semaphore</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="c1">// only one worker will enter the &quot;critical_section&quot; at any time</span>
<span class="k">for</span><span class="p">(</span><span class="kt">size_t</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">acquire</span><span class="p">(</span><span class="n">semaphore</span><span class="p">);</span>
<span class="w"> </span><span class="n">critical_section</span><span class="p">();</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">release</span><span class="p">(</span><span class="n">semaphore</span><span class="p">);</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">}</span></pre>
</div></section>
<section class="m-doc-details" id="a83ebb3537650dd6e7ea32a60ece8462c"><div>
<h3>
<div class="m-doc-template">
template&lt;typename I, std::enable_if_t&lt;std::is_same_v&lt;deref_t&lt;I&gt;, <a href="classtf_1_1Semaphore.html" class="m-doc">Semaphore</a>&gt;, void&gt;* = nullptr&gt;
</div>
<span class="m-doc-wrap-bumper">void tf::<wbr />Runtime::<wbr /></span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#a83ebb3537650dd6e7ea32a60ece8462c" class="m-doc-self">release</a>(</span><span class="m-doc-wrap">I first,
I last)</span></span>
</h3>
<p>releases the given range of semaphores</p>
<table class="m-table m-fullwidth m-flat">
<thead>
<tr><th colspan="2">Template parameters</th></tr>
</thead>
<tbody>
<tr>
<td style="width: 1%">I</td>
<td>iterator type</td>
</tr>
</tbody>
<thead>
<tr><th colspan="2">Parameters</th></tr>
</thead>
<tbody>
<tr>
<td>first</td>
<td>iterator to the beginning (inclusive)</td>
</tr>
<tr>
<td>last</td>
<td>iterator to the end (exclusive)</td>
</tr>
</tbody>
</table>
<p>Releases the given range of semaphores.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">tf</span><span class="o">::</span><span class="n">Semaphore</span><span class="o">&gt;</span><span class="w"> </span><span class="n">semaphores</span><span class="p">;</span>
<span class="n">semaphores</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="n">semaphores</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="k">auto</span><span class="w"> </span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">semaphores</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
<span class="k">auto</span><span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">semaphores</span><span class="p">.</span><span class="n">end</span><span class="p">();</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="c1">// only one worker will enter the &quot;critical_section&quot; at any time</span>
<span class="k">for</span><span class="p">(</span><span class="kt">size_t</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">&lt;</span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">async</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Runtime</span><span class="o">&amp;</span><span class="w"> </span><span class="n">rt</span><span class="p">){</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">acquire</span><span class="p">(</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">);</span>
<span class="w"> </span><span class="n">critical_section</span><span class="p">();</span>
<span class="w"> </span><span class="n">rt</span><span class="p">.</span><span class="n">release</span><span class="p">(</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">);</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">}</span></pre>
</div></section>
</section>
</div>
</div>
</div>
</article></main>
<div class="m-doc-search" id="search">
<a href="#!" onclick="return hideSearch()"></a>
<div class="m-container">
<div class="m-row">
<div class="m-col-m-8 m-push-m-2">
<div class="m-doc-search-header m-text m-small">
<div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
<div id="search-symbolcount">&hellip;</div>
</div>
<div class="m-doc-search-content">
<form>
<input type="search" name="q" id="search-input" placeholder="Loading &hellip;" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
</form>
<noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
<div id="search-help" class="m-text m-dim m-text-center">
<p class="m-noindent">Search for symbols, directories, files, pages or
modules. You can omit any prefix from the symbol or file path; adding a
<code>:</code> or <code>/</code> suffix lists all members of given symbol or
directory.</p>
<p class="m-noindent">Use <span class="m-label m-dim">&darr;</span>
/ <span class="m-label m-dim">&uarr;</span> to navigate through the list,
<span class="m-label m-dim">Enter</span> to go.
<span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
copy a link to the result using <span class="m-label m-dim"></span>
<span class="m-label m-dim">L</span> while <span class="m-label m-dim"></span>
<span class="m-label m-dim">M</span> produces a Markdown link.</p>
</div>
<div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
<ul id="search-results"></ul>
</div>
</div>
</div>
</div>
</div>
<script src="search-v2.js"></script>
<script src="searchdata-v2.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<p>Taskflow handbook is part of the <a href="https://taskflow.github.io">Taskflow project</a>, copyright © <a href="https://tsung-wei-huang.github.io/">Dr. Tsung-Wei Huang</a>, 2018&ndash;2024.<br />Generated by <a href="https://doxygen.org/">Doxygen</a> 1.9.1 and <a href="https://mcss.mosra.cz/">m.css</a>.</p>
</div>
</div>
</div>
</nav></footer>
</body>
</html>