C++ 异步任务
外观
C++异步任务是C++多线程编程中的重要概念,通过`<future>`和`<thread>`等头文件提供的工具,允许开发者以非阻塞方式执行任务并获取结果。本页详细介绍其核心组件、使用方法和实际应用场景。
概述[编辑 | 编辑源代码]
异步任务(Asynchronous Task)允许程序在后台执行耗时操作(如计算、I/O),同时主线程继续处理其他任务。C++11引入的`std::async`、`std::future`和`std::promise`为此提供了标准化支持。
关键优势包括:
- 非阻塞执行:主线程无需等待任务完成。
- 结果获取:通过`future`对象延迟获取返回值或异常。
- 资源管理:自动处理线程生命周期。
核心组件[编辑 | 编辑源代码]
std::async[编辑 | 编辑源代码]
启动异步任务,返回`std::future`对象。语法:
#include <future>
#include <iostream>
int compute() {
return 42; // 模拟耗时计算
}
int main() {
std::future<int> result = std::async(std::launch::async, compute);
std::cout << "Main thread continues..." << std::endl;
std::cout << "Result: " << result.get() << std::endl; // 阻塞直至结果就绪
return 0;
}
输出:
Main thread continues... Result: 42
参数`std::launch::async`强制创建新线程,而`std::launch::deferred`延迟执行(调用`get()`时运行)。
std::future[编辑 | 编辑源代码]
表示异步操作的结果,提供以下方法:
- `get()`:获取结果(若未就绪则阻塞)。
- `wait()`:等待结果就绪。
- `valid()`:检查结果是否可用。
std::promise[编辑 | 编辑源代码]
允许显式设置值或异常,与`std::future`配对使用:
void set_value(std::promise<int>&& prom) {
prom.set_value(100);
}
int main() {
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread t(set_value, std::move(prom));
std::cout << "Future value: " << fut.get() << std::endl;
t.join();
return 0;
}
实际案例[编辑 | 编辑源代码]
并行计算[编辑 | 编辑源代码]
计算两个向量的点积,分解为多个异步任务:
#include <vector>
#include <numeric>
#include <future>
double dot_product(const std::vector<double>& a, const std::vector<double>& b, size_t start, size_t end) {
return std::inner_product(a.begin() + start, a.begin() + end, b.begin() + start, 0.0);
}
int main() {
std::vector<double> a(1000, 1.0), b(1000, 2.0);
auto fut1 = std::async(std::launch::async, dot_product, std::ref(a), std::ref(b), 0, 500);
auto fut2 = std::async(std::launch::async, dot_product, std::ref(a), std::ref(b), 500, 1000);
double result = fut1.get() + fut2.get();
std::cout << "Dot product: " << result << std::endl; // 输出 2000
}
超时处理[编辑 | 编辑源代码]
使用`std::future::wait_for`实现超时控制:
std::future<int> fut = std::async([](){
std::this_thread::sleep_for(std::chrono::seconds(5));
return 123;
});
if (fut.wait_for(std::chrono::seconds(2)) == std::future_status::timeout) {
std::cout << "Task timeout\n";
} else {
std::cout << "Result: " << fut.get() << "\n";
}
进阶主题[编辑 | 编辑源代码]
异常传递[编辑 | 编辑源代码]
异步任务中的异常会通过`future::get()`重新抛出:
auto fut = std::async([](){
throw std::runtime_error("Error in async task");
});
try {
fut.get();
} catch (const std::exception& e) {
std::cerr << "Caught: " << e.what() << std::endl;
}
线程池集成[编辑 | 编辑源代码]
结合自定义线程池优化资源使用(伪代码):
ThreadPool pool(4); // 4个工作线程
auto fut = pool.enqueue([](){ return /* ... */; });
性能考虑[编辑 | 编辑源代码]
- 频繁创建线程的开销较大,建议复用线程(如线程池)。
- `std::async`默认策略由实现决定,显式指定`std::launch::async`或`deferred`以避免歧义。
总结[编辑 | 编辑源代码]
C++异步任务简化了多线程编程,适合I/O密集型或可并行计算场景。通过`future`/`promise`模型,开发者可以高效管理任务依赖和结果同步。