In our application, we defined a calculate function that should take a long time to run. Technically, our function calculates the square of an integer argument, but we added an artificial delay to make it run for 1 second. We use a sleep_for standard library function to add a delay to the application:
std::this_thread::sleep_for(std::chrono::seconds(1));
Besides calculations, the function logs to the console when it started working, when it completed, and how much time it took.
Next, we defined a test function that invokes the calculate function, to demonstrate how asynchronous invocation works.
The function has two parameters. The first parameter is a value that is passed to the calculate function. The second parameter is the amount of time the test function is going to spend after running the calculate function and before requesting the result. This way, we model the useful work the function can perform in parallel to the calculations it requested.
The test function starts working by running the calculate function in asynchronous mode and passing it the first parameter, value:
std::future<int> fut = std::async (calculate, value);
The async function implicitly spawns a thread and starts the execution of the calculate function.
Since we run the function asynchronously, the result is not yet ready. Instead, the async function returns an instance of std::future, an object that will hold the result when it is available.
Next, we simulate the useful work. In our case, it is the pause for the specified interval of time. After the work that can be done in parallel is completed, we need to get the result of the calculate function to proceed. To request the result, we use the get method of our std::future object, as shown:
int result = fut.get();
The get method blocks until the result is available. Then, we can calculate the amount of time we have spent waiting for the result, and output the result—along with the wait time—to the console.
In the main function, we run the test function to evaluate two scenarios:
- The useful work takes less time than the calculation of the result.
- The useful work takes more time than the calculation of the result.
Running the application produces the following output.
In the first scenario, we can see that we are starting the calculations, and then started waiting for the result before the calculation has been completed. As a result, the get method blocked for 600 milliseconds until the result was ready:
In the second scenario, the useful work took 1200 milliseconds. As we can see, the calculation has been done before the result was requested, and because of that, the get method did not block, and immediately returned the result.