Cancel a Running Taskflow
Contents
This chapters discusses how to cancel a submitted or a running taskflow graph.
Request Cancellation
When you submit a taskflow to an executor (e.g., tf::
tf::Executor executor; tf::Taskflow taskflow; for(int i=0; i<1000; i++) { taskflow.emplace([](){ std::this_thread::sleep_for(std::chrono::seconds(1)); }); } // submit the taskflow tf::Future fu = executor.run(taskflow); // request to cancel the submitted execution above fu.cancel(); // wait until the cancellation finishes fu.get();
When you request a cancellation, the executor will stop scheduling the rest tasks of the taskflow. Tasks that are already running at the time of requesting cancellation 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 until a cancellation completes, you must explicitly call tf::Future::get
.
For instance, the following code results in undefined behavior:
tf::Executor executor; { tf::Taskflow taskflow; for(int i=0; i<1000; i++) { taskflow.emplace([](){}); } tf::Future fu = executor.run(taskflow); fu.cancel(); // there can still be task running after cancellation } // destroying taskflow here can result in undefined behavior
The undefined behavior problem exists because tf::get
to ensure the cancellation completes before the end of the scope destroys the taskflow.
tf::Executor executor; { tf::Taskflow taskflow; for(int i=0; i<1000; i++) { taskflow.emplace([](){}); } tf::Future fu = executor.run(taskflow); fu.cancel(); // there can still be task running after cancellation fu.get(); // waits until the cancellation completes }