docs/RequestCancellation.html
This chapters discusses how to cancel a running taskflow.
When you submit a taskflow to an executor using the run series (e.g., tf::Executor::run), the executor returns a tf::Future object that holds the result of the execution. tf::Future is derived from std::future. In addition to the base methods of std::future, you can call tf::Future::cancel to cancel the execution of a running taskflow. The following example demonstrates cancelling a submission of a taskflow containing 1000 tasks, each running for one second.
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 taskflowtf::Future\<void\> fu = executor.run(taskflow);// request to cancel the above submitted executionfu.cancel();// wait until the cancellation completesfu.wait();
When you request a cancellation, the executor will stop scheduling the remaining tasks of the taskflow. Requesting a cancellation does not guarantee an immediate stop of a running taskflow. Tasks that are already running will continue to finish, but their successor tasks will not be scheduled. A cancellation is considered complete only after all running tasks have finished. To wait for the cancellation to complete, you can explicitly call tf::Future::wait. Note that it is your responsibility to ensure that the taskflow remains alive until the cancellation is complete, as there may still be running tasks that cannot be canceled. 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
To avoid this issue, call wait to ensure the cancellation completes before the taskflow is destroyed at the end of the scope.
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 cancellationfu.wait();// wait until the cancellation completes}
Due to its asynchronous and non-deterministic nature, taskflow cancellation has the following limitations:
We may overcome these limitations in the future releases.