Algorithms, Blockchain and Cloud

Tutorial on C++ Future, Async and Promise


In C++, std::future and std::async are part of the C++11 standard’s concurrency library. They allow you to run tasks asynchronously and obtain results later, making them useful for writing non-blocking code and parallelizing computations. Here’s a breakdown of how they work and how they’re typically used:

C++ std::async

std::async is a high-level function that allows you to launch a task (a callable, such as a function or lambda) asynchronously. You specify a function to run, and std::async returns a std::future that represents the result of the function. You can later retrieve this result, either when the task completes or whenever you need it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <future>
#include <chrono>
 
int compute() {
    std::this_thread::sleep_for(std::chrono::seconds(2));  // Simulate work
    return 42;  // Result of the computation
}
 
int main() {
    // Launch the task asynchronously
    std::future<int> result = std::async(std::launch::async, compute);
 
    // Perform other tasks while compute() is running...
 
    // Get the result of compute() (this will wait if the task isn’t done)
    int value = result.get();
    std::cout << "Result: " << value << std::endl;
 
    return 0;
}
#include <iostream>
#include <future>
#include <chrono>

int compute() {
    std::this_thread::sleep_for(std::chrono::seconds(2));  // Simulate work
    return 42;  // Result of the computation
}

int main() {
    // Launch the task asynchronously
    std::future<int> result = std::async(std::launch::async, compute);

    // Perform other tasks while compute() is running...

    // Get the result of compute() (this will wait if the task isn’t done)
    int value = result.get();
    std::cout << "Result: " << value << std::endl;

    return 0;
}

In this example:

  • std::async(std::launch::async, compute) launches compute() asynchronously, returning a std::future object.
  • The result.get() call waits for the task to complete if it hasn’t yet finished and then retrieves the result.

C++ std::launch Policy

  • std::launch::async: Forces the task to run asynchronously on a new thread.
  • std::launch::deferred: Delays execution until get() or wait() is called on the future, effectively making it synchronous.

If you omit the policy, C++ may choose either, depending on implementation-defined criteria.

C++ std::future

std::future is a class template that represents a result to be obtained later. It’s essentially a placeholder for the result of an asynchronous operation.

Key Methods

  • get(): Waits for the result if it hasn’t finished and then retrieves it. After calling get(), the std::future becomes empty.
  • wait(): Waits until the task completes, but doesn’t retrieve the result.
  • valid(): Returns true if the std::future has a shared state (i.e., a result is available).
  • wait_for() and wait_until(): Wait for a specific amount of time or until a deadline for the result to be available.

Example with wait_for

1
2
3
4
5
if (result.wait_for(std::chrono::seconds(1)) == std::future_status::ready) {
    std::cout << "Result is ready: " << result.get() << std::endl;
} else {
    std::cout << "Still waiting for the result..." << std::endl;
}
if (result.wait_for(std::chrono::seconds(1)) == std::future_status::ready) {
    std::cout << "Result is ready: " << result.get() << std::endl;
} else {
    std::cout << "Still waiting for the result..." << std::endl;
}

This code checks if the result is ready within 1 second. If not, it continues without blocking.

C++ std::promise

For more advanced use, std::promise allows you to manually set the result of a std::future. A std::promise object provides a std::future, and you set the result explicitly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <future>
#include <thread>
 
void setPromise(std::promise<int> p) {
    p.set_value(10);  // Set the result of the promise
}
 
int main() {
    std::promise<int> p;
    std::future<int> f = p.get_future();  // Get the future from the promise
 
    std::thread t(setPromise, std::move(p));  // Pass the promise to a thread
    t.join();
 
    std::cout << "Result from promise: " << f.get() << std::endl;  // Get the result
    return 0;
}
#include <iostream>
#include <future>
#include <thread>

void setPromise(std::promise<int> p) {
    p.set_value(10);  // Set the result of the promise
}

int main() {
    std::promise<int> p;
    std::future<int> f = p.get_future();  // Get the future from the promise

    std::thread t(setPromise, std::move(p));  // Pass the promise to a thread
    t.join();

    std::cout << "Result from promise: " << f.get() << std::endl;  // Get the result
    return 0;
}

In this example, the result 10 is set by std::promise, which std::future can retrieve with f.get().

C++ Future/Async/Promise Summary

  • std::async: Launches a task that runs asynchronously, returning a std::future.
  • std::future: Represents a value that will be set in the future, usually the return value of an asynchronous task.
  • std::promise: Allows manually setting the result for a std::future.

Using these, you can effectively manage asynchronous tasks in C++, making it easier to run computations in parallel or offload work to other threads without blocking the main thread.

–EOF (The Ultimate Computing & Technology Blog) –

844 words
Last Post: Teaching Kids Programming - Delete Nodes From Linked List Present in Array
Next Post: Understanding Availability Percentages: Calculating Downtime for Your Systems

The Permanent URL is: Tutorial on C++ Future, Async and Promise (AMP Version)

Exit mobile version