Introduction
In addition to providing portable wrappers for native multi-threading facilities, C++ also provides higher level constructs that allow the programmer to call functions asynchronously.
Future
Consider:
#include <future> #include <iostream> int main(int argc, char* argv[]) { using namespace std; future<int> f = async([](int x, int y){return x + y; }, 5, 6); cout << f.get() << endl; return 0; }
Here f
is of type future<int>. The async function may be computed in a separate thread or it may be computed on demand. However you could force it to run in the same thread or another thread by specifying launch::deferred
or launch::async
respectively as the first parameter. Either way f.get()
blocks until the result is obtained.
Promise
A promise
is wrapper around future
. Consider:
promise<int> p; auto f = p.get_future(); p.set_value(100); cout << f.get() << endl; return 0;
The value ‘100’ will be printed as output. By setting a value on the promise the related future gets updated. The promise can also set an exception in which case an exception will be thrown when the related future’s get()
is called.
Packaged Task
A packaged_task
is essentially a function object that wraps another function object so that the result or exception is captured in a promise. A future associated with the promise can then be used to retrieve the result as shown in example below
int const rows = 480; double img[rows]; // init img somehow auto t = packaged_task<decltype(accum)>(accum); auto f = t.get_future(); t(&img[0], &img[0] +rows, 0.0); cout << f.get() << endl;
where accum
is defined as:
double accum(double* start, double *finish, double init) { return std::accumulate(start, finish, init); }