<li><ahref="#CancelARunningTaskflow">Cancel Execution of Taskflows</a></li>
<li><ahref="#UnderstandTheLimitationsOfCancellation">Understand the Limitations of Cancellation</a></li>
</ul>
</nav>
<p>This chapters discusses how to cancel submitted tasks.</p><sectionid="CancelARunningTaskflow"><h2><ahref="#CancelARunningTaskflow">Cancel Execution of Taskflows</a></h2><p>When you submit a taskflow to an executor (e.g., <ahref="classtf_1_1Executor.html#a519777f5783981d534e9e53b99712069" class="m-doc">tf::<wbr/>Executor::<wbr/>run</a>), the executor returns a <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> object that will hold the result of the execution. <ahref="classtf_1_1Future.html" class="m-doc">tf::<wbr/>Future</a> is a derived class from <ahref="http://en.cppreference.com/w/cpp/thread/future.html" class="m-doc-external">std::<wbr/>future</a>. In addition to base methods of <ahref="http://en.cppreference.com/w/cpp/thread/future.html" class="m-doc-external">std::<wbr/>future</a>, you can call <ahref="classtf_1_1Future.html#a3bf5f104864ab2590b6409712d3a469b" class="m-doc">tf::<wbr/>Future::<wbr/>cancel</a> to cancel the execution of a running taskflow. The following example cancels a submission of a taskflow that contains 1000 tasks each running one second.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">;</span>
<spanclass="c1">// wait until the cancellation completes</span>
<spanclass="n">fu</span><spanclass="p">.</span><spanclass="n">get</span><spanclass="p">();</span></pre><asideclass="m-note m-warning"><h4>Attention</h4><p><ahref="classtf_1_1Future.html#a3bf5f104864ab2590b6409712d3a469b" class="m-doc">tf::<wbr/>Future::<wbr/>cancel</a> is <em>non-deterministic</em> and <em>out-of-order</em>.</p></aside><p>When you request a cancellation, the executor will stop scheduling the rest tasks of the taskflow. Tasks that are already running will continue to finish, but their successor tasks will not be scheduled to run. A cancellation is considered complete when all these running tasks finish. To wait for a cancellation to complete, you may explicitly call <code>tf::Future::get</code>.</p><asideclass="m-note m-warning"><h4>Attention</h4><p>It is your responsibility to ensure that the taskflow remains alive before the cancellation completes.</p></aside><p>For instance, the following code results in undefined behavior:</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">;</span>
<spanclass="w"></span><spanclass="n">fu</span><spanclass="p">.</span><spanclass="n">cancel</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// there can still be task running after cancellation</span>
<spanclass="p">}</span><spanclass="w"></span><spanclass="c1">// destroying taskflow here can result in undefined behavior</span></pre><p>The undefined behavior problem exists because <ahref="classtf_1_1Future.html#a3bf5f104864ab2590b6409712d3a469b" class="m-doc">tf::<wbr/>Future::<wbr/>cancel</a> does not guarantee an immediate cancellation. To fix the problem, call <code>get</code> to ensure the cancellation completes before the end of the scope destroys the taskflow.</p><preclass="m-code"><spanclass="n">tf</span><spanclass="o">::</span><spanclass="n">Executor</span><spanclass="w"></span><spanclass="n">executor</span><spanclass="p">;</span>
<spanclass="w"></span><spanclass="n">fu</span><spanclass="p">.</span><spanclass="n">cancel</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// there can still be task running after cancellation</span>
<spanclass="w"></span><spanclass="n">fu</span><spanclass="p">.</span><spanclass="n">get</span><spanclass="p">();</span><spanclass="w"></span><spanclass="c1">// waits until the cancellation completes</span>
<spanclass="p">}</span></pre></section><sectionid="UnderstandTheLimitationsOfCancellation"><h2><ahref="#UnderstandTheLimitationsOfCancellation">Understand the Limitations of Cancellation</a></h2><p>Canceling the execution of a running taskflow has the following limitations:</p><ul><li>Cancellation is non-preemptive. A running task will not be cancelled until it finishes.</li><li>Cancelling a taskflow with tasks acquiring and/or releasing <ahref="classtf_1_1Semaphore.html" class="m-doc">tf::<wbr/>Semaphore</a> results is currently not supported.</li></ul><p>We may overcome these limitations in the future releases.</p></section>
</div>
</div>
</div>
</article></main>
<divclass="m-doc-search" id="search">
<ahref="#!" onclick="return hideSearch()"></a>
<divclass="m-container">
<divclass="m-row">
<divclass="m-col-m-8 m-push-m-2">
<divclass="m-doc-search-header m-text m-small">
<div><spanclass="m-label m-default">Tab</span> / <spanclass="m-label m-default">T</span> to search, <spanclass="m-label m-default">Esc</span> to close</div>