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) –
Last Post: Teaching Kids Programming - Delete Nodes From Linked List Present in Array
Next Post: Understanding Availability Percentages: Calculating Downtime for Your Systems