C++11coreintermediate
std::async (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
Launches a function asynchronously (potentially in a new thread) and returns a `std::future` holding the result, providing the simplest way to run tasks concurrently.
Real-World Scenario
Fetch data from multiple remote services in parallel and combine the results.
Quick Snippet
snippet.cpp
#include <future>
auto fut1 = std::async(std::launch::async, fetchFromServiceA);
auto fut2 = std::async(std::launch::async, fetchFromServiceB);
auto result = combine(fut1.get(), fut2.get());Full Example
async.cpp
// CodeNebula - C++11 Example: std::async
// Compile: g++ -std=c++11 -Wall -Wextra -pthread -o example async.cpp
//
// This example demonstrates:
// - std::async for launching asynchronous tasks
// - std::launch::async (new thread) vs std::launch::deferred (lazy)
// - Default launch policy (implementation-defined)
// - Collecting results from multiple async tasks
// - Practical use: parallel computation
#include <iostream>
#include <future>
#include <vector>
#include <string>
#include <chrono>
#include <numeric>
#include <cmath>
// ============================================================
// 1. Basic async usage
// ============================================================
int heavyComputation(int n) {
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum += i * i;
}
return sum;
}
std::string fetchData(const std::string& source) {
// Simulate network delay
std::this_thread::sleep_for(std::chrono::milliseconds(50));
return "Data from " + source;
}
// ============================================================
// 2. Launch policies
// ============================================================
void demonstratePolicies() {
std::cout << "--- Launch policies ---" << std::endl;
// std::launch::async: guaranteed new thread
auto asyncResult = std::async(std::launch::async, []() {
std::cout << " async policy: thread "
<< std::this_thread::get_id() << std::endl;
return 1;
});
// std::launch::deferred: lazy evaluation (runs on get())
auto deferredResult = std::async(std::launch::deferred, []() {
std::cout << " deferred policy: thread "
<< std::this_thread::get_id() << std::endl;
return 2;
});
std::cout << " Main thread: " << std::this_thread::get_id() << std::endl;
std::cout << " (deferred not yet executed)" << std::endl;
asyncResult.get();
std::cout << " Calling deferred.get() now..." << std::endl;
deferredResult.get(); // Executes HERE, on the calling thread
}
// ============================================================
// 3. Parallel computation
// ============================================================
double partialSum(const std::vector<double>& data, size_t start, size_t end) {
double sum = 0.0;
for (size_t i = start; i < end; ++i) {
sum += data[i];
}
return sum;
}
double parallelSum(const std::vector<double>& data, int numTasks) {
size_t chunkSize = data.size() / static_cast<size_t>(numTasks);
std::vector<std::future<double>> futures;
for (int i = 0; i < numTasks; ++i) {
size_t start = static_cast<size_t>(i) * chunkSize;
size_t end = (i == numTasks - 1) ? data.size() : start + chunkSize;
futures.push_back(
std::async(std::launch::async, partialSum,
std::cref(data), start, end)
);
}
double total = 0.0;
for (auto& f : futures) {
total += f.get();
}
return total;
}
// ============================================================
// 4. Multiple independent tasks
// ============================================================
struct TaskResult {
std::string name;
int value;
};
int main() {
std::cout << "=== std::async ===" << std::endl;
// Basic async
std::cout << "\n--- Basic async ---" << std::endl;
auto f1 = std::async(std::launch::async, heavyComputation, 100);
auto f2 = std::async(std::launch::async, fetchData, "server-1");
auto f3 = std::async(std::launch::async, fetchData, "server-2");
std::cout << " Tasks launched, doing other work..." << std::endl;
std::cout << " Sum of squares(1..100) = " << f1.get() << std::endl;
std::cout << " " << f2.get() << std::endl;
std::cout << " " << f3.get() << std::endl;
// Launch policies
std::cout << std::endl;
demonstratePolicies();
// Parallel sum
std::cout << "\n--- Parallel computation ---" << std::endl;
std::vector<double> data(10000);
for (size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<double>(i + 1);
}
auto start = std::chrono::steady_clock::now();
double pSum = parallelSum(data, 4);
auto end = std::chrono::steady_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
double expected = 10000.0 * 10001.0 / 2.0;
std::cout << " Parallel sum: " << pSum << std::endl;
std::cout << " Expected: " << expected << std::endl;
std::cout << " Time: " << dur.count() << " us" << std::endl;
// Collecting multiple results
std::cout << "\n--- Multiple async results ---" << std::endl;
std::vector<std::future<int>> futures;
for (int i = 1; i <= 5; ++i) {
futures.push_back(std::async(std::launch::async, [i]() {
return i * i;
}));
}
for (int i = 0; i < 5; ++i) {
std::cout << " " << (i + 1) << "^2 = " << futures[i].get() << std::endl;
}
return 0;
}
// Expected output:
// === std::async ===
//
// --- Basic async ---
// Tasks launched, doing other work...
// Sum of squares(1..100) = 338350
// Data from server-1
// Data from server-2
//
// --- Launch policies ---
// Main thread: 140...
// async policy: thread 140...
// (deferred not yet executed)
// Calling deferred.get() now...
// deferred policy: thread 140... (same as main)
//
// --- Parallel computation ---
// Parallel sum: 5.0005e+07
// Expected: 5.0005e+07
// Time: ... us
//
// --- Multiple async results ---
// 1^2 = 1
// 2^2 = 4
// 3^2 = 9
// 4^2 = 16
// 5^2 = 25
Run command
g++ -std=c++11 -Wall -Wextra -pthread -o example async.cpp