Taskflow's executor provides an STL-style method, tf::Executor::async, that allows you to run a callable object asynchronously. This method returns a std::future which will eventually hold the result of the function call.
If you do not need the return value or do not require a std::future for synchronization, you should use tf::Executor::silent_async. This method returns nothing and incurs less overhead than tf::Executor::async, as it avoids the cost of managing a shared state for std::future.
executor.silent_async([](){});
Launching asynchronous tasks from an executor is thread-safe and can be invoked from multiple threads, including both worker threads inside the executor and external threads outside of it. The scheduler automatically detects the source of the submission and employs work-stealing to schedule the task efficiently, ensuring balanced workload distribution across workers.
tf::Taskmy_task=taskflow.emplace([&](){// launch an asynchronous task from my_taskexecutor.async([&](){// launch another asynchronous task that may be run by another workerexecutor.async([&](){});})});executor.run(taskflow);executor.wait_for_all();// wait for all tasks to finish
tf::Taskflowtaskflow;tf::Executorexecutor;std::atomic<int>counter{0};taskflow.emplace([&](tf::Runtime&rt){for(inti=0;i<100;i++){rt.silent_async([&](){++counter;}));}rt.corun();// all of the 100 asynchronous tasks will finish by this joinassert(counter==100);});executor.run(taskflow).wait();
Unlike tf::Subflow::join, you can call tf::Runtime::corun multiple times to synchronize the execution of asynchronous tasks between different runs. For example, the following code spawn 100 asynchronous tasks twice and join each execution to assure the spawned 100 asynchronous tasks have properly completed.
tf::Taskflowtaskflow;tf::Executorexecutor;std::atomic<int>counter{0};taskflow.emplace([&](tf::Runtime&rt){// spawn 100 asynchronous tasks and joinfor(inti=0;i<100;i++){rt.silent_async([&](){++counter;}));}rt.corun();// all of the 100 asynchronous tasks will finish by this joinassert(counter==100);// spawn another 100 asynchronous tasks and joinfor(inti=0;i<100;i++){rt.silent_async([&](){++counter;}));}rt.corun();// all of the 100 asynchronous tasks will finish by this joinassert(counter==200);});executor.run(taskflow).wait();
By default, tf::Runtime does not join like tf::Subflow. All pending asynchronous tasks spawned from a tf::Runtime become uncontrollable once their parent runtime goes out of scope. It is user's responsibility to explicitly synchronize these tasks using tf::Runtime::corun.
Asynchronous tasks can take a reference to tf::Runtime, allowing them to recursively launch additional asynchronous tasks. Combined with tf::Runtime::corun, this enables the implementation of various recursive parallelism patterns, including parallel sort, divide-and-conquer algorithms, and the fork-join model. For instance, the example below demonstrates a parallel recursive implementation of Fibonacci numbers using recursive asynchronous tasking from tf::Runtime:
#include<taskflow/taskflow.hpp>size_tfibonacci(size_tN,tf::Runtime&rt){if(N<2)returnN;size_tres1,res2;rt.silent_async([N,&res1](tf::Runtime&rt1){res1=fibonacci(N-1,rt1);});// tail optimization for the right childres2=fibonacci(N-2,rt);// use corun to avoid blocking the worker from waiting the two children tasks // to finishrt.corun();returnres1+res2;}intmain(){tf::Executorexecutor;size_tN=5,res;executor.silent_async([N,&res](tf::Runtime&rt){res=fibonacci(N,rt);});executor.wait_for_all();std::cout<<N<<"-th Fibonacci number is "<<res<<'\n';return0;}
The figure below shows the execution diagram, where the suffix *_1 represent the left child spawned by its parent runtime.
Tab / T to search, Esc to close
โฆ
Search for symbols, directories, files, pages or
modules. You can omit any prefix from the symbol or file path; adding a
: or / suffix lists all members of given symbol or
directory.
Use โ
/ โ to navigate through the list,
Enter to go.
Tab autocompletes common prefix, you can
copy a link to the result using โL while โM produces a Markdown link.