C++ 的 std::future
库是 C++11 标准引入的一个并发编程工具,它允许异步编程和结果检索。std::future
通常与 std::async
、std::promise
和 std::packaged_task
一起使用,以支持异步操作。
1. std::async
std::async
函数用于在单独的线程中异步地启动函数调用,并返回一个 std::future
对象,该对象用于获取异步调用的结果。
#include <iostream>
#include <future>
int myFunction(int a) {
// 模拟一些计算工作
std::this_thread::sleep_for(std::chrono::seconds(1));
return a * 2;
}
int main() {
// 异步启动函数
std::future<int> fut = std::async(std::launch::async, myFunction, 10);
// 等待异步操作完成
// 注意:std::future::get() 会阻塞,直到结果可用
int result = fut.get();
std::cout << "Result: " << result << std::endl;
return 0;
}
2. std::future
std::future
是一个模板类,它代表了一个异步操作的结果。你可以使用 std::future::get()
方法来获取异步操作的结果。如果异步操作尚未完成,get()
方法会阻塞,直到结果可用。
3. std::promise
和 std::packaged_task
std::promise
允许你在一个线程中设置结果(或异常),然后在另一个线程中通过std::future
获取该结果。std::packaged_task
是一个将可调用对象(如函数、lambda 表达式或函数对象)包装为异步任务的类。它内部使用std::promise
和std::future
来管理异步操作的结果。
注意事项
- 使用
std::async
时,确保传递std::launch::async
作为第一个参数,以确保函数在单独的线程中异步执行。如果不传递此参数,std::async
可能会同步地调用函数(这取决于实现和调用上下文)。 - 当你不再需要
std::future
对象时,确保它不被销毁,直到你已经调用了get()
或wait()
,或者你确定异步操作已经完成。否则,你可能会丢失异步操作的结果。 - 注意异常安全性。如果异步函数抛出异常,而你没有在调用
get()
时捕获它,该异常将在get()
被调用时重新抛出。